@@ -230,6 +230,18 @@ function canApplyUpdates() {
230
230
return module . hot . status ( ) === 'idle' ;
231
231
}
232
232
233
+ function canAcceptErrors ( ) {
234
+ // NOTE: This var is injected by Webpack's DefinePlugin, and is a boolean instead of string.
235
+ const hasReactRefresh = process . env . FAST_REFRESH ;
236
+
237
+ const status = module . hot . status ( ) ;
238
+ // React refresh can handle hot-reloading over errors.
239
+ // However, when hot-reload status is abort or fail,
240
+ // it indicates the current update cannot be applied safely,
241
+ // and thus we should bail out to a forced reload for consistency.
242
+ return hasReactRefresh && [ "abort" , "fail" ] . indexOf ( status ) === - 1
243
+ }
244
+
233
245
// Attempt to update code on the fly, fall back to a hard reload.
234
246
function tryApplyUpdates ( onHotUpdateSuccess ) {
235
247
if ( ! module . hot ) {
@@ -243,11 +255,13 @@ function tryApplyUpdates(onHotUpdateSuccess) {
243
255
}
244
256
245
257
function handleApplyUpdates ( err , updatedModules ) {
246
- // NOTE: This var is injected by Webpack's DefinePlugin, and is a boolean instead of string.
247
- const hasReactRefresh = process . env . FAST_REFRESH ;
248
- const wantsForcedReload = err || ! updatedModules || hadRuntimeError ;
249
- // React refresh can handle hot-reloading over errors.
250
- if ( ! hasReactRefresh && wantsForcedReload ) {
258
+ const haveErrors = err || hadRuntimeError ;
259
+ // When there is no error but updatedModules is unavailable,
260
+ // it indicates a critical failure in hot-reloading,
261
+ // e.g. server is not ready to serve new bundle,
262
+ // and hence we need to do a forced reload.
263
+ const needsForcedReload = ! err && ! updatedModules ;
264
+ if ( ( haveErrors && ! canAcceptErrors ( ) ) || needsForcedReload ) {
251
265
window . location . reload ( ) ;
252
266
return ;
253
267
}
0 commit comments