Skip to content

Commit

Permalink
fix: handle early JS errors like in Metro (#829)
Browse files Browse the repository at this point in the history
* fix: forward early JS errors to ErrorUtils

* feat: disable strict error handling from webpack/rspack

* fix: typing for ModuleObject

* chore: update setups for testers

* chore: add changeset

* fix: typing in tests

* chore: add comment about ErrorUtils

* fix: handle scenario were ErrorUtils are not initialized yet

* chore: add reference to guardedLoadModule in Metro
  • Loading branch information
jbroma authored Dec 18, 2024
1 parent b1a010a commit 617c501
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/late-crabs-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@callstack/repack": patch
---

Fix early JS errors not being displayed in LogBox
1 change: 1 addition & 0 deletions apps/tester-app/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# Note that this is incompatible with web debugging.
newArchEnabled=true
bridgelessEnabled=true
hermesEnabled=true

# Uncomment the line below to build React Native from source.
#react.buildFromSource=true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jest.mock('../NativeScriptManager', () => ({
}));

globalThis.__webpack_require__ = {
i: [],
u: (id: string) => `${id}.chunk.bundle`,
p: () => '',
repack: {
Expand Down
19 changes: 19 additions & 0 deletions packages/repack/src/modules/ScriptManager/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
type ModuleExports = Record<string | number | symbol, any>;

type ModuleObject = {
id: number;
loaded: boolean;
error?: any;
exports: ModuleExports;
};

export interface WebpackContext {
i: ((options: {
id: number;
factory: (
moduleObject: ModuleObject,
moduleExports: ModuleExports,
webpackRequire: WebpackContext
) => void;
module: ModuleObject;
require: WebpackContext;
}) => void)[];
p: () => string;
u: (id: string) => string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ export class RepackTargetPlugin implements RspackPluginInstance {
compiler.options.output.chunkFormat = 'array-push';
compiler.options.output.globalObject = globalObject;

// Disable built-in strict module error handling
// this is handled through an interceptor in the
// init module added to __webpack_require__.i array
compiler.options.output.strictModuleErrorHandling = false;

// Normalize global object.
new compiler.webpack.BannerPlugin({
raw: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,28 @@ module.exports = function () {

__webpack_require__.repack = $globalObject$.__repack__ = repackRuntime;

// intercept module factory calls to forward errors to global.ErrorUtils
// aligned with `guardedLoadModule` behaviour in Metro
// https://github.com/facebook/metro/blob/a4cb0b0e483748ef9f1c760cb60c57e3a84c1afd/packages/metro-runtime/src/polyfills/require.js#L329
__webpack_require__.i.push(function (options) {
var originalFactory = options.factory;
options.factory = function (moduleObject, moduleExports, webpackRequire) {
try {
originalFactory.call(this, moduleObject, moduleExports, webpackRequire);
} catch (e) {
if ($globalObject$.ErrorUtils) {
// exposed as global early on, part of `@react-native/js-polyfills` error-guard
// https://github.com/facebook/react-native/blob/4dac99cf6d308e804efc098b37f5c24c1eb611cf/packages/polyfills/error-guard.js#L121
$globalObject$.ErrorUtils.reportFatalError(e);
} else {
// error happened before ErrorUtils was initialized
// at this point in runtime we can only rethrow the error
throw e;
}
}
};
});

function loadScript(
name: string,
caller: string | undefined,
Expand Down

0 comments on commit 617c501

Please sign in to comment.