From 3982a2c6bd116a6dcc6ee6889e4a246b710b70a7 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Wed, 26 Oct 2022 20:09:32 -0700 Subject: [PATCH] Log Abnormal Closes to Metro Websocket Summary: We are running into a group seeing frequent disconnects from Metro in a specific office. These are surfaced (at least on iOS) as websocket closures, without a prior websocket error. WebSocket closure can be for a variety of reasons, and the spec for a CloseEvent is to include fields `wasClean`, `code`, and `reason`, with `code` having the most well-defined meaning. This change makes it so that we emit extra context when the websocket is closed. That should help inform developers the reason behind any close that may be abnormal. Changelog: [General][Added] - Log Abnormal Closes to Metro Websocket Reviewed By: motiz88 Differential Revision: D40660765 fbshipit-source-id: ef606d8d809af1c697a78eb00cc5666c29a8bca3 --- Libraries/Utilities/HMRClient.js | 18 ++++++++++++++++-- Libraries/WebSocket/WebSocket.js | 9 ++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) 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();