bikeshaving / crank

The Just JavaScript Framework
https://crank.js.org
MIT License
2.7k stars 75 forks source link

Catching errors in a simple function component #207

Closed waynebaylor closed 3 years ago

waynebaylor commented 3 years ago

If you take the example from the docs about catching errors:

function Thrower() { 
  throw new Error("Hmmm");
}

function *Catcher() {
  try {
    yield <Thrower />;
  } catch (err) {
    return <div>Error: {err.message}</div>;
  }
}

and modify Catcher so it's a simple function instead of a generator:

function Thrower() { 
  throw new Error("Hmmm");
}

function Catcher() {
  try {
    return <Thrower />;
  } catch (err) {
    return <div>Error: {err.message}</div>;
  }
}

then the catch block doesn't get executed.

Not sure if it's a bug or if my expectations are off 😄 Example: https://codesandbox.io/s/catch-error-simple-function-chfpx

brainkim commented 3 years ago

Sweats bullets

Not a bug! The way error handling works is that, when an error is thrown, we walk up the component tree and pass the error into any generator components via the throw() method. The best way to conceptualize the throw() method is to imagine that it resumes the generator but throws an error from the position suspended yield operator. There is no corresponding way to throw errors with return statements, so this feature is exclusive to generator components.

Let me know your thoughts on this!

waynebaylor commented 3 years ago

Yeah that makes sense, I hadn't thought about the throws() part.

waynebaylor commented 3 years ago

I think I was forgetting that in general executing <SomeComponent/> isn't the same as rendering. If there are errors during the rendering then Crank needs some way to get that info back into the components, like using throws().