diff --git a/Libraries/Utilities/HMRClient.js b/Libraries/Utilities/HMRClient.js index 6a56826866e24a..b37f5961d2e0b3 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -241,9 +241,23 @@ Error: ${e.message}`; } }); - client.on('close', data => { + client.on('close', closeEvent => { LoadingView.hide(); - setHMRUnavailableReason('Disconnected from Metro.'); + + // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1 + // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5 + const isNormalOrUnsetCloseReason = + closeEvent.code === 1000 || + closeEvent.code === 1005 || + closeEvent.code == null; + + if (isNormalOrUnsetCloseReason) { + setHMRUnavailableReason('Disconnected from Metro.'); + } else { + setHMRUnavailableReason( + `Disconnected from Metro (${closeEvent.code}: "${closeEvent.reason}").`, + ); + } }); if (isEnabled) { diff --git a/Libraries/WebSocket/WebSocket.js b/Libraries/WebSocket/WebSocket.js index b2093b3af28a4b..3fdde2b3639adf 100644 --- a/Libraries/WebSocket/WebSocket.js +++ b/Libraries/WebSocket/WebSocket.js @@ -43,6 +43,10 @@ const CLOSED = 3; const CLOSE_NORMAL = 1000; +// Abnormal closure where no code is provided in a control frame +// https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5 +const CLOSE_ABNORMAL = 1006; + const WEBSOCKET_EVENTS = ['close', 'error', 'message', 'open']; let nextWebSocketId = 0; @@ -260,6 +264,7 @@ class WebSocket extends (EventTarget(...WEBSOCKET_EVENTS): any) { new WebSocketEvent('close', { code: ev.code, reason: ev.reason, + // TODO: missing `wasClean` (exposed on iOS as `clean` but missing on Android) }), ); this._unregisterEvents(); @@ -277,7 +282,9 @@ class WebSocket extends (EventTarget(...WEBSOCKET_EVENTS): any) { ); this.dispatchEvent( new WebSocketEvent('close', { - message: ev.message, + code: CLOSE_ABNORMAL, + reason: ev.message, + // TODO: Expose `wasClean` }), ); this._unregisterEvents();