Skip to content

Commit eb7948b

Browse files
authored
Improve termination screen (#160)
* add launch id to termination screen * add devtools disconnected reasons * allow displaying custom errors to the user for when devtools is disconnected
1 parent cbb8c83 commit eb7948b

File tree

6 files changed

+112
-19
lines changed

6 files changed

+112
-19
lines changed

front_end/global_typings/react_native.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ declare global {
1010
var enableReactNativePerfMetrics: boolean|undefined;
1111
var enableReactNativePerfMetricsGlobalPostMessage: boolean|undefined;
1212
var enableReactNativeOpenInExternalEditor: boolean|undefined;
13+
var enableDisplayingFullDisconnectedReason: boolean|undefined;
1314
var reactNativeOpenInEditorButtonImage: string|undefined;
1415
var FB_ONLY__reactNativeFeedbackLink: string|undefined;
1516
var FB_ONLY__enablePerformance: any;

front_end/panels/rn_welcome/RNWelcome.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type * as Common from '../../core/common/common.js';
77
import * as UI from '../../ui/legacy/legacy.js';
88
import * as Host from '../../core/host/host.js';
99
import * as i18n from '../../core/i18n/i18n.js';
10+
import * as Root from '../../core/root/root.js';
1011
import * as SDK from '../../core/sdk/sdk.js';
1112

1213
import rnWelcomeStyles from './rnWelcome.css.js';
@@ -25,6 +26,8 @@ const UIStrings = {
2526
docsLabel: 'Debugging docs',
2627
/** @description "What's new" link */
2728
whatsNewLabel: "What's new",
29+
/** @description Description for sharing the session ID of the current session with the user */
30+
sessionIdMessage: "[FB-only] The session ID for this React Native DevTools lauch is: ",
2831
/** @description "Debugging Basics" title (docs item 1) */
2932
docsDebuggingBasics: 'Debugging Basics',
3033
/** @description "Debugging Basics" item detail */
@@ -132,6 +135,8 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements
132135
import.meta.url,
133136
).toString();
134137

138+
const launchId = Root.Runtime.Runtime.queryParam('launchId');
139+
135140
render(html`
136141
<div class="rn-welcome-panel">
137142
<header class="rn-welcome-hero">
@@ -162,6 +167,13 @@ export class RNWelcomeImpl extends UI.Widget.VBox implements
162167
${i18nString(UIStrings.whatsNewLabel)}
163168
</x-link>
164169
</div>
170+
${launchId ? html`
171+
<div class="rn-session-id">
172+
${i18nString(UIStrings.sessionIdMessage)}
173+
<br/>
174+
${launchId}
175+
</div>
176+
` : ''}
165177
${this.#reactNativeVersion !== null && this.#reactNativeVersion !== undefined ? html`
166178
<p class="rn-welcome-version">React Native: <code>${this.#reactNativeVersion}</code></p>
167179
` : null}

front_end/panels/rn_welcome/rnWelcome.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@
101101
border-right: 1px solid var(--color-details-hairline);
102102
}
103103

104+
.rn-session-id {
105+
display: flex;
106+
align-items: center;
107+
margin-top: 24px;
108+
user-select: all;
109+
}
110+
104111
.rn-welcome-version {
105112
position: fixed;
106113
top: 8px;

front_end/ui/legacy/RemoteDebuggingTerminatedScreen.ts

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import * as Host from '../../core/host/host.js';
66
import * as i18n from '../../core/i18n/i18n.js';
7+
import * as Root from '../../core/root/root.js';
78
import type * as Platform from '../../core/platform/platform.js';
89
import * as LitHtml from '../../ui/lit-html/lit-html.js';
910

@@ -24,6 +25,12 @@ const UIStrings = {
2425
* (see https://developer.chrome.com/docs/devtools/remote-debugging/).
2526
*/
2627
debuggingConnectionWasClosed: 'Debugging connection was closed. Reason: ',
28+
/**
29+
* @description Text in a dialog box in DevTools providing extra details on why remote debugging has been terminated.
30+
* "Remote debugging" here means that DevTools on a PC is inspecting a website running on an actual mobile device
31+
* (see https://developer.chrome.com/docs/devtools/remote-debugging/).
32+
*/
33+
debuggingConnectionWasClosedDetails: 'Details: ',
2734
/**
2835
* @description Text in a dialog box showing how to reconnect to DevTools when remote debugging has been terminated.
2936
* "Remote debugging" here means that DevTools on a PC is inspecting a website running on an actual mobile device
@@ -50,6 +57,11 @@ const UIStrings = {
5057
* @description Text in a dialog box to prompt for feedback if the disconnection is unexpected.
5158
*/
5259
sendFeedbackMessage: '[FB-only] Please send feedback if this disconnection is unexpected.',
60+
/**
61+
* @description Text in a dialog box to prompt for feedback if the disconnection is unexpected,
62+
* telling the user what's their session ID for easier debugging
63+
*/
64+
sendFeedbackLaunchIdMessage: 'Please include the following session ID:',
5365
/**
5466
* @description Label of the FB-only 'send feedback' button.
5567
*/
@@ -62,7 +74,11 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
6274
const {render, html} = LitHtml;
6375

6476
export class RemoteDebuggingTerminatedScreen extends VBox {
65-
constructor(reason: string, onClose?: () => void) {
77+
constructor(
78+
reason: string,
79+
connectionLostDetails?: {reason?: string, code?: string, errorType?: string},
80+
onClose?: () => void
81+
) {
6682
super(true);
6783
this.registerCSSFiles([remoteDebuggingTerminatedScreenStyles]);
6884

@@ -75,27 +91,35 @@ export class RemoteDebuggingTerminatedScreen extends VBox {
7591
html`
7692
<h1 class="remote-debugging-terminated-title">${i18nString(UIStrings.title)}</h1>
7793
<div class="remote-debugging-terminated-message">
78-
<span>${i18nString(UIStrings.debuggingConnectionWasClosed)}</span>
79-
<span class="remote-debugging-terminated-reason">${reason}</span>
94+
<div>${i18nString(UIStrings.debuggingConnectionWasClosed)}</div>
95+
<div class="remote-debugging-terminated-reason">${reason}</div>
96+
${globalThis.enableDisplayingFullDisconnectedReason ?
97+
html`
98+
<div>
99+
${i18nString(UIStrings.debuggingConnectionWasClosedDetails)}
100+
</div>
101+
<div class="remote-debugging-terminated-reason">
102+
<textarea disabled rows="5">${JSON.stringify(connectionLostDetails, null, 2)}</textarea>
103+
</div>
104+
` : ''}
80105
</div>
106+
${feedbackLink !== null && feedbackLink !== undefined ? this.#createFeedbackSection(feedbackLink) : null}
81107
<div class="remote-debugging-terminated-options">
82108
<div class="remote-debugging-terminated-label">
83109
${i18nString(UIStrings.reconnectWhenReadyByReopening)}
84110
</div>
85-
${
86-
createTextButton(
87-
i18nString(UIStrings.reconnectDevtools),
88-
handleReconnect,
89-
{className: 'primary-button', jslogContext: 'reconnect'},
90-
)}
111+
${createTextButton(
112+
i18nString(UIStrings.reconnectDevtools),
113+
handleReconnect,
114+
{className: 'primary-button', jslogContext: 'reconnect'},
115+
)}
91116
<div class="remote-debugging-terminated-label">
92117
${i18nString(UIStrings.closeDialogDetail)}
93118
</div>
94119
${createTextButton(i18nString(UIStrings.closeDialog), onClose, {
95120
jslogContext: 'dismiss',
96121
})}
97122
</div>
98-
${feedbackLink !== null && feedbackLink !== undefined ? this.#createFeedbackSection(feedbackLink) : null}
99123
`,
100124
this.contentElement,
101125
{host: this},
@@ -109,7 +133,7 @@ export class RemoteDebuggingTerminatedScreen extends VBox {
109133
const dialog = new Dialog('remote-debnugging-terminated');
110134
dialog.setSizeBehavior(SizeBehavior.MeasureContent);
111135
dialog.setDimmed(true);
112-
new RemoteDebuggingTerminatedScreen(uiMessage, () => dialog.hide()).show(dialog.contentElement);
136+
new RemoteDebuggingTerminatedScreen(uiMessage, connectionLostDetails, () => dialog.hide()).show(dialog.contentElement);
113137
dialog.show();
114138
Host.rnPerfMetrics.remoteDebuggingTerminated(connectionLostDetails);
115139
}
@@ -121,9 +145,22 @@ export class RemoteDebuggingTerminatedScreen extends VBox {
121145
);
122146
};
123147

148+
const launchId = Root.Runtime.Runtime.queryParam('launchId');
149+
124150
return html`
125151
<div class="remote-debugging-terminated-feedback-container">
126152
<div class="remote-debugging-terminated-feedback-label">${i18nString(UIStrings.sendFeedbackMessage)}</div>
153+
${launchId ?
154+
html`
155+
<div class="remote-debugging-terminated-feedback-label">
156+
${i18nString(UIStrings.sendFeedbackLaunchIdMessage)}
157+
</div>
158+
<div class="remote-debugging-terminated-feedback-launch-id">
159+
${launchId}
160+
</div>
161+
` : ''
162+
}
163+
<br/>
127164
${
128165
createTextButton(
129166
i18nString(UIStrings.sendFeedback),

front_end/ui/legacy/components/utils/TargetDetachedDialog.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,21 @@ const UIStrings = {
1313
*@description Text on the remote debugging window to indicate the connection is lost
1414
*/
1515
websocketDisconnected: 'WebSocket disconnected',
16+
/**
17+
*@description Text on the remote debugging window to indicate the connection cannot be made because the device is not connected
18+
*/
19+
websocketDisconnectedUnregisteredDevice: 'The corresponding app for this DevTools session cannot be found. Please relaunch DevTools from the terminal.',
20+
/**
21+
*@description Text on the remote debugging window to indicate the connection to corresponding device was lost
22+
*/
23+
websocketDisconnectedConnectionLost: 'Connection lost to corresponding device'
1624
};
25+
26+
const DisconnectedReasonsUIStrings = {
27+
UREGISTERED_DEVICE: UIStrings.websocketDisconnectedUnregisteredDevice,
28+
CONNECTION_LOST: UIStrings.websocketDisconnectedConnectionLost
29+
}
30+
1731
const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/utils/TargetDetachedDialog.ts', UIStrings);
1832
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
1933
export class TargetDetachedDialog extends SDK.SDKModel.SDKModel<void> implements ProtocolProxyApi.InspectorDispatcher {
@@ -33,9 +47,25 @@ export class TargetDetachedDialog extends SDK.SDKModel.SDKModel<void> implements
3347
UI.RemoteDebuggingTerminatedScreen.RemoteDebuggingTerminatedScreen.show(reason);
3448
}
3549

50+
static getCustomUiReason(connectionLostDetails?: {reason?: string, code?: string, errorType?: string}): string | null {
51+
if (!connectionLostDetails) {
52+
return null;
53+
}
54+
55+
if (connectionLostDetails.code === "1011" && connectionLostDetails.reason?.includes('[UREGISTERED_DEVICE]')) {
56+
return i18nString(DisconnectedReasonsUIStrings.UREGISTERED_DEVICE);
57+
}
58+
59+
if (connectionLostDetails.code === "1000" && connectionLostDetails.reason?.includes('[CONNECTION_LOST]')) {
60+
return i18nString(DisconnectedReasonsUIStrings.CONNECTION_LOST);
61+
}
62+
63+
return null;
64+
}
65+
3666
static webSocketConnectionLost(connectionLostDetails?: {reason?: string, code?: string, errorType?: string}): void {
37-
UI.RemoteDebuggingTerminatedScreen.RemoteDebuggingTerminatedScreen.show(
38-
i18nString(UIStrings.websocketDisconnected), connectionLostDetails);
67+
const uiReason = TargetDetachedDialog.getCustomUiReason(connectionLostDetails) || i18nString(UIStrings.websocketDisconnected);
68+
UI.RemoteDebuggingTerminatedScreen.RemoteDebuggingTerminatedScreen.show(uiReason, connectionLostDetails);
3969
}
4070

4171
targetCrashed(): void {

front_end/ui/legacy/remoteDebuggingTerminatedScreen.css

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
.widget {
88
padding: 20px;
9+
user-select: text;
910
}
1011

1112
.remote-debugging-terminated-title {
@@ -17,16 +18,14 @@
1718
.remote-debugging-terminated-message {
1819
font-size: 14px;
1920
margin: 5px 0;
20-
margin-bottom: 24px;
21+
margin-bottom: 16px;
2122
}
2223

2324
.remote-debugging-terminated-options {
2425
display: grid;
2526
grid-template-columns: 1fr auto;
2627
grid-gap: 8px;
2728
align-items: center;
28-
padding-top: 12px;
29-
border-top: 1px solid var(--color-details-hairline-light);
3029
}
3130

3231
.remote-debugging-terminated-label {
@@ -45,21 +44,28 @@
4544
display: flex;
4645
flex-direction: column;
4746
align-items: center;
48-
margin-top: 16px;
4947
padding: 12px 16px;
5048
background-color: var(--color-background-elevation-1);
5149
border-radius: 6px;
50+
margin-bottom: 12px;
5251
}
5352

5453
.remote-debugging-terminated-feedback-label {
5554
font-size: 14px;
5655
margin-bottom: 8px;
5756
}
5857

59-
.remote-debugging-terminated-reason {
60-
--override-reason-color: #8b0000;
58+
.remote-debugging-terminated-feedback-launch-id {
59+
color: red;
60+
}
6161

62+
.remote-debugging-terminated-reason {
63+
--override-reason-color: red;
6264
color: var(--override-reason-color);
65+
margin: 8px;
66+
textarea {
67+
width: 100%;
68+
}
6369
}
6470

6571
.theme-with-dark-background .reason,

0 commit comments

Comments
 (0)