From 87e0c2e135b64c335f3975ccc877abeeef589897 Mon Sep 17 00:00:00 2001 From: Michael Mok Date: Mon, 12 Jul 2021 00:51:51 +0200 Subject: [PATCH] feat: initialise socket with exponential retry --- client/ErrorOverlayEntry.js | 8 ++++++-- client/utils/retry.js | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 client/utils/retry.js diff --git a/client/ErrorOverlayEntry.js b/client/ErrorOverlayEntry.js index 1a94b3a9..214bffc4 100644 --- a/client/ErrorOverlayEntry.js +++ b/client/ErrorOverlayEntry.js @@ -3,6 +3,7 @@ import { handleError, handleUnhandledRejection } from './utils/errorEventHandlers.js'; import formatWebpackErrors from './utils/formatWebpackErrors.js'; import runWithPatchedUrl from './utils/patchUrl.js'; +import runWithRetry from './utils/retry.js'; // Setup error states let isHotReload = false; @@ -75,8 +76,11 @@ if (process.env.NODE_ENV !== 'production' && typeof window !== 'undefined') { runWithPatchedUrl(function setupOverlay() { // Only register if no other overlay have been registered if (!window.__reactRefreshOverlayInjected && __react_refresh_socket__) { - // Registers handlers for compile errors - __react_refresh_socket__.init(compileMessageHandler, __resourceQuery); + // Registers handlers for compile errors with retry - + // This is to prevent mismatching injection order causing errors to be thrown + runWithRetry(function initSocket() { + __react_refresh_socket__.init(compileMessageHandler, __resourceQuery); + }, 3); // Registers handlers for runtime errors handleError(function handleError(error) { hasRuntimeErrors = true; diff --git a/client/utils/retry.js b/client/utils/retry.js new file mode 100644 index 00000000..2d92eec2 --- /dev/null +++ b/client/utils/retry.js @@ -0,0 +1,20 @@ +function runWithRetry(callback, maxRetries) { + function executeWithRetryAndTimeout(currentCount) { + try { + if (currentCount > maxRetries - 1) { + console.warn('[React Refresh] Failed set up the socket connection.'); + return; + } + + callback(); + } catch (err) { + setTimeout(function () { + executeWithRetryAndTimeout(currentCount + 1); + }, Math.pow(10, currentCount)); + } + } + + executeWithRetryAndTimeout(0); +} + +export default runWithRetry;