Aldwin Vlasblom
Aug 28, 2017 · 2 min read

In order for exception sub-classing to be a reliable tool for gracefully handling expected failures, you have to be sure that all exceptions raised by your code, as well as those raised by the libraries you use, conform strictly to the scheme you’re using for distinguishing them from bugs. This also goes for the inverse case: you have to be sure that bugs (like bad input to a function) are not accidentally handled like expected failures.

Another way to say it is that by mixing expected failures with bugs, you miss an opportunity for information preservation. Now it has to be preserved some other way. In the case of Promises, it’s left to the discretion of the developer to ensure up front that the information is created in a way that it can be preserved, and everyone has to be in on it. This is one of these “risk mitigation” techniques that I mention later in the article, which are needed when working with Promises.

Yet another way to look at it is from the perspective of type consistency. I know JavaScript doesn’t have a type system, but I believe developers still benefit from keeping their types consistent. The fact that Promises catch exceptions and put them in the rejection branch changes the type of the rejection from T to T | Error in every Promise (ignoring that in JavaScript, anything can be thrown, so it really just becomes any). Mixed types are more work to handle properly, and again this is left as an exercise to the user.


In conclusion, I do believe that you can handle expected failures “quite well” despite the chance for random data being exposed to your handler. But if you want to handle failures really well, you need to be able to trust your tool to give you expected failures and nothing else.

)

    Aldwin Vlasblom

    Written by

    Author of https://github.com/fluture-js/Fluture; Working at https://wearereasonablepeople.nl/