Skip to content

Commit

Permalink
Re-throw module.error when instantiating runtime modules (#4918)
Browse files Browse the repository at this point in the history
### Description

Runtime modules can be executed multiple times within the same context.
However, when such a module encounters a runtime error during execution,
this error is cached in module.error and not properly re-thrown when the
module is required again from `getOrInstantiateRuntimeModule`, which
means that on later runs we’ll silently fail to instantiate the module,
and run into any errors that expects a global side-effect from the
module.

link WEB-1045
  • Loading branch information
alexkirsz committed May 15, 2023
1 parent 833ce23 commit 7d2a57f
Show file tree
Hide file tree
Showing 36 changed files with 1,044 additions and 720 deletions.
49 changes: 29 additions & 20 deletions crates/turbopack-dev/js/src/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,9 @@ function instantiateModule(id, source) {
break;
}

runModuleExecutionHooks(module, (refresh) => {
try {
// NOTE(alexkirsz) This can fail when the module encounters a runtime error.
try {
runModuleExecutionHooks(module, (refresh) => {
moduleFactory.call(module.exports, {
e: module.exports,
r: commonJsRequire.bind(null, module),
Expand All @@ -501,11 +502,11 @@ function instantiateModule(id, source) {
k: refresh,
__dirname: module.id.replace(/(^|\/)[\/]+$/, ""),
});
} catch (error) {
module.error = error;
throw error;
}
});
});
} catch (error) {
module.error = error;
throw error;
}

module.loaded = true;
if (module.namespaceObject && module.exports !== module.namespaceObject) {
Expand All @@ -530,21 +531,26 @@ function runModuleExecutionHooks(module, executeModule) {
? globalThis.$RefreshInterceptModuleExecution$(module.id)
: () => {};

executeModule({
register: globalThis.$RefreshReg$,
signature: globalThis.$RefreshSig$,
});
try {
executeModule({
register: globalThis.$RefreshReg$,
signature: globalThis.$RefreshSig$,
});

if ("$RefreshHelpers$" in globalThis) {
// This pattern can also be used to register the exports of
// a module with the React Refresh runtime.
registerExportsAndSetupBoundaryForReactRefresh(
module,
globalThis.$RefreshHelpers$
);
if ("$RefreshHelpers$" in globalThis) {
// This pattern can also be used to register the exports of
// a module with the React Refresh runtime.
registerExportsAndSetupBoundaryForReactRefresh(
module,
globalThis.$RefreshHelpers$
);
}
} catch (e) {
throw e;
} finally {
// Always cleanup the intercept, even if module execution failed.
cleanupReactRefreshIntercept();
}

cleanupReactRefreshIntercept();
}

/**
Expand Down Expand Up @@ -1418,6 +1424,9 @@ function instantiateRuntimeModule(moduleId, chunkPath) {
function getOrInstantiateRuntimeModule(moduleId, chunkPath) {
const module = moduleCache[moduleId];
if (module) {
if (module.error) {
throw module.error;
}
return module;
}

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7d2a57f

Please sign in to comment.