DEV Community

Discussion on: Errors Are Not Exceptions

Collapse
 
devinrhode2 profile image
Devin Rhode • Edited

I think, this safeCall is nice when you are calling external libraries/functions that are hard to change to return [thing, error].

I am currently converting a 4-5 throw statements to:

return [
  undefined,
  new Error('asdf')
]
Enter fullscreen mode Exit fullscreen mode

The nice thing about this, is that the consumer/caller does not need to check:

const maybeThing = dangerousCall();
if (maybeThing instanceof Error) {}
Enter fullscreen mode Exit fullscreen mode

They can simply:

const [thing, error] = dangerousCall();
if (error) {}
Enter fullscreen mode Exit fullscreen mode

However, once we destructure, the "Either or ness" disappears. Type of thing and error are both Thing | undefined and Error | undefined. While basics like this work

if (error) {
  // TS knows that `thing` is defined
}
Enter fullscreen mode Exit fullscreen mode

There are instances where you want to pass the whole tuple, maybeThing.

I'm curious what a good variable name is for this maybeThing.

Collapse
 
devinrhode2 profile image
Devin Rhode • Edited

Update: I recommend using an object style return. The array brackets are cute, but less useful. Positional args are fragile, and while this is only two, if you want to give a special error code or warning, then a simple new Error('asdf') can't represent either of these two (at least not very clearly).

So you may typically do:

return { error: new Error('asdf') }
Enter fullscreen mode Exit fullscreen mode

but you may occassionally:

return {
  warning: 'Update skipped. Provided data is the same.',
  errorCode: 'update_skipped',
}
Enter fullscreen mode Exit fullscreen mode

Note to self: I don't think I have any code that actually uses this idea. Was just a pure idea.