preact icon indicating copy to clipboard operation
preact copied to clipboard

Preact 10 more difficult to debug uncaught errors than Preact 8.

Open PepsRyuu opened this issue 5 years ago • 4 comments

Recently giving Preact 10 a try after using Preact 8 for a very long time, but having massive difficulties working with it cause of the inability to properly debug with it.

Let's say I had something like the following:

class MyComponent extends Component {
    componentDidMount () {
        a + b; // throws an uncaught error
    }

    render () {
        return <div>Hello World</div>
    }
}

In Preact 8, this will happen:

preact8

In Preact 10, this will happen:

preact10

In Preact 8, it's super easy to see what went wrong, and to inspect variables and try out different snippets of code to try and fix the issue. In Preact 10 because of the try/catch for supporting componentDidCatch, I can't do that anymore, making it really frustrating to identify the issue and solve it, especially when using eval source maps where you can't often can't use the stack trace to click on the relevant line.

Is there any way to resolve this? Can Preact's code be re-organised so that there's no try/catch if there's no componentDidCatch in the component tree? This issue can make fixing code fairly time consuming so would appreciate any thoughts you have.

Thanks! 🙂

PepsRyuu avatar Feb 09 '20 17:02 PepsRyuu

We need some form of exception catching in core in order to support componentDidCatch, but perhaps there's a way to make it conditional on the existence of a componentDidCatch somewhere in the tree. That wouldn't solve all cases, but it would at least fix the case where nothing is catching and we're just rethrowing the unmodified error.

FWIW as a short-term fix, if you check the "Pause on caught exceptions" box, the debugger will pause in the same place it used to in 8.x (and then again where you noted it pausing in 10, though you can blackbox preact.js to disable that).

developit avatar Feb 11 '20 17:02 developit

React avoids caught exception issues in debug with its invokeGuardedCallbackImpl. I can understand that including this sort of mechanism might bloat the package. (Well, it could be included for non-minified debug builds only, but I don't know if most Preact users run this sort of build in practice.)

I would be interested in either a built-in solution, or some way that I could provide my own sort of invokeGuardedCallbackImpl implementation for Preact to use at runtime.

options.invokeGuardedCallback = function(callback) {
    /* does something like invokeGuardedCallbackImpl to invoke callback */
}

The existence check on componentDidCatch would also be a good solution for my use case.

wnayes avatar Feb 14 '20 15:02 wnayes

Interesting - we have a hook called options. _catchError - maybe this could be a replacement for that hook?

developit avatar Feb 27 '20 20:02 developit

Maybe for dev mode you can use setTimeout at the beginning and clearTimeout at the end of critical section. So if timeout is cleared - no error has occurred. If timeout is triggered - you invoke componentDidCatch. Debugging is really much harder in v10. I just removed all try catch out of preact.js and debugging become beautiful.

Megabyteceer avatar Sep 12 '22 05:09 Megabyteceer