react-native-exception-handler icon indicating copy to clipboard operation
react-native-exception-handler copied to clipboard

Undefined error and isFatal

Open donmezemre opened this issue 4 years ago • 2 comments

When i try to navigate some not buggy screens, exceptionHandler function of setJSExceptionHandler is returns undefined error and isFatal params. Has anyone encountered this problem and how can i handle this?

My react native version is 0.60.2.

-That is what the library returns Screen Shot 2020-11-11 at 14 11 50

-Code that i used Screen Shot 2020-11-11 at 14 13 30

donmezemre avatar Nov 11 '20 11:11 donmezemre

Had the same issue, so I digged a bit.

I found that under the hood, this library calls a RN built-in global error handling utility:

global.ErrorUtils.setGlobalHandler(customHandler)

That means that your handler will be called when something reports an error to this utility through:

global.ErrorUtils.reportError(error)

Thus, an undefined error in your handler comes form a call such as

global.ErrorUtils.reportError(undefined)

I looked for such call and I found none in my code. In my case it actually came from the library itself (https://github.com/a7ul/react-native-exception-handler/blob/master/index.js#L16):

console.error = (message, error) => global.ErrorUtils.reportError(error);

The line overrides console.error and replaces the original behavior (printing the error to the console) with a report to the global RN error handler. I understand this may help centralize error reports, but it is a bit sneaky: one can expect that calling console.error will only print the error and have no side effect, while here it propagates the error instead.

Anyway, this fails to handle the case where console.error is called without an error, e.g.

console.error("Something went wrong")

In my case, I came across this issue after upgrading to a newer react-native version that called console.error with a deprecation warning message.

Such call propagates an undefined error through the RN global error handler, which ultimately provides an undefined error to your handler, thus breaching the handler type signature where an Error is expected:

type JSExceptionHandler = (error: Error, isFatal: boolean) => void

This issue can be fixed in the library: forward the Error if there is one, create one from the message otherwise:

console.error = (message, error) => global.ErrorUtils.reportError(error ? error : Error(message))

If the library authors or someone else wants to use that to patch the library, help yourself!

In the meantime, here is a workaround that overrides the overriding in your App (remove the type cast to any if you don't use TS):

setJSExceptionHandler((error, isFatal) => {
     // ....
}, true)
console.error = (message, error) => (global as any).ErrorUtils.reportError(error ? error : Error(message))

noullet avatar Dec 16 '20 17:12 noullet

@a7ul Sorry to ask. do you think a work around on this ticket? I have the same issue reported by @donmezemre Thanks!

tiveor avatar Mar 01 '21 16:03 tiveor