ErrorOverlayEntry.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /* global __react_refresh_error_overlay__, __react_refresh_socket__, __resourceQuery */
  2. const events = require('./utils/errorEventHandlers.js');
  3. const formatWebpackErrors = require('./utils/formatWebpackErrors.js');
  4. const runWithPatchedUrl = require('./utils/patchUrl.js');
  5. const runWithRetry = require('./utils/retry.js');
  6. // Setup error states
  7. let isHotReload = false;
  8. let hasRuntimeErrors = false;
  9. /**
  10. * Try dismissing the compile error overlay.
  11. * This will also reset runtime error records (if any),
  12. * because we have new source to evaluate.
  13. * @returns {void}
  14. */
  15. function tryDismissErrorOverlay() {
  16. __react_refresh_error_overlay__.clearCompileError();
  17. __react_refresh_error_overlay__.clearRuntimeErrors(!hasRuntimeErrors);
  18. hasRuntimeErrors = false;
  19. }
  20. /**
  21. * A function called after a compile success signal is received from Webpack.
  22. * @returns {void}
  23. */
  24. function handleCompileSuccess() {
  25. isHotReload = true;
  26. if (isHotReload) {
  27. tryDismissErrorOverlay();
  28. }
  29. }
  30. /**
  31. * A function called after a compile errored signal is received from Webpack.
  32. * @param {string[]} errors
  33. * @returns {void}
  34. */
  35. function handleCompileErrors(errors) {
  36. isHotReload = true;
  37. const formattedErrors = formatWebpackErrors(errors);
  38. // Only show the first error
  39. __react_refresh_error_overlay__.showCompileError(formattedErrors[0]);
  40. }
  41. /**
  42. * Handles compilation messages from Webpack.
  43. * Integrates with a compile error overlay.
  44. * @param {*} message A Webpack HMR message sent via WebSockets.
  45. * @returns {void}
  46. */
  47. function compileMessageHandler(message) {
  48. switch (message.type) {
  49. case 'ok':
  50. case 'still-ok':
  51. case 'warnings': {
  52. // TODO: Implement handling for warnings
  53. handleCompileSuccess();
  54. break;
  55. }
  56. case 'errors': {
  57. handleCompileErrors(message.data);
  58. break;
  59. }
  60. default: {
  61. // Do nothing.
  62. }
  63. }
  64. }
  65. if (process.env.NODE_ENV !== 'production') {
  66. if (typeof window !== 'undefined') {
  67. runWithPatchedUrl(function setupOverlay() {
  68. // Only register if no other overlay have been registered
  69. if (!window.__reactRefreshOverlayInjected && __react_refresh_socket__) {
  70. // Registers handlers for compile errors with retry -
  71. // This is to prevent mismatching injection order causing errors to be thrown
  72. runWithRetry(function initSocket() {
  73. __react_refresh_socket__.init(compileMessageHandler, __resourceQuery);
  74. }, 3);
  75. // Registers handlers for runtime errors
  76. events.handleError(function handleError(error) {
  77. hasRuntimeErrors = true;
  78. __react_refresh_error_overlay__.handleRuntimeError(error);
  79. });
  80. events.handleUnhandledRejection(function handleUnhandledPromiseRejection(error) {
  81. hasRuntimeErrors = true;
  82. __react_refresh_error_overlay__.handleRuntimeError(error);
  83. });
  84. // Mark overlay as injected to prevent double-injection
  85. window.__reactRefreshOverlayInjected = true;
  86. }
  87. });
  88. }
  89. }