2

It is easy to find opinions that consider it bad practice to use exceptions for non-exceptional events, here is an example:

Definitely not exceptions. A failed login is hardly an "exceptional" case and it just a normal course of logic for the application. If you use an exception then you'll always have to wrap logging in with an exception handler for no other reason than to handle the case of a failed login. That seems like the very definition of using exceptions for logic flow, which isn't right.

https://stackoverflow.com/a/22807812/1283776

It is equally easy to find opinions that consider it good practice to reject promises for non-exceptional events, here is an example:

When you have an asynchronous operation with a promise interface, one would usually reject the Promise with an Error object as the reject reason to signify an error. That's the core design theory of promises.

https://stackoverflow.com/a/56918433/1283776

Why does the general community consider it bad practice to throw errors for non-exceptional events and reject promises for the same? The reason for my confusion is that these to error passing constructs seem very similar to me. Here is how I would need to handle them in client code:

Login is synchronous and throws an error if unsuccessful:

try {
  login(credentials)
  // get token
} catch (err) {
  // print: unable to login
}

Login is asynchronous and rejects a promise if unsuccessful:

try {
  await login(credentials)
  // get token
} catch (err) {
  // print: unable to login
}
user1283776
  • 19,640
  • 49
  • 136
  • 276
  • 1
    I suspect a lot of it comes from personal preference - a coherent argument could easily be made either way. I suspect the only time it's really unanimously bad practice is if you're hijacking an error path and 'assuming' you know what went wrong - that way you might be at risk of unknown unknowns. – Mark Taylor Jul 31 '20 at 07:16
  • Closely related: [Why are exceptions used for rejecting promises in JS?](https://stackoverflow.com/q/21616432/1048572) – Bergi Jul 31 '20 at 08:24
  • 1
    I'd think it has a lot to do with the fact that a promise *is* a return value, very similar to a tagged enum in that it either "contains" a result or an error, and that [`.then(…, …)` can be used wonderfully for branching](https://stackoverflow.com/q/24662289/1048572). This was however before the advent of `async`/`await`, which has made rejections much more similar to exceptions. – Bergi Jul 31 '20 at 08:27

0 Answers0