> Promises attempt to resolve this by coercing all exceptions to error passing, but not all exceptions are safe to be passed. Specifically, any exception originating from core that is not an invalid argument exception (think 4XX vs 5XX class errors) cannot safely be caught / coerced / continued on. Also, not all errors passed to callbacks are even theoretically passable as the unofficial policy of core is that core callback errors are only distinguishable from exceptions in that they occur after the origin tick. In other words, they are equally crash-worthy and equally non-crash-worthy.
This is not true. With promises, the wrapper of core functionality is left up to you. You can either write a crashy wrapper, an uncrashy wrapper, or a wrapper which picks whether to crash or not depending on the kind of error. I wrote more about this here [1]
Most default wrappers provided by promise libraries catch all synchronous errors but don't do anything with asynchronous errors. So far, this seems to be a fine default -- most unrecoverable, state-corrupting thrown errors in node core are asynchronous, and all the invalid argument errors are synchronous. But even if that weren't the case, it would be a simple matter to write a more specific wrapper.
You're talking about the core/userland boundary beyond the origin tick, and we're both right. Promises coerce caught exceptions occurring on the origin tick to errors (bad), while allowing non-caught async errors to be handled in a custom manner as you point out.
The comments following your linked comment address this nuance. I agree with Raynos that the core of the issue is as I point out here, 2 divergent incompatible error handling mechanisms, with both of them fundamentally broken:
* error passing fails because we don't have CPS due to lack of Proper Tail Calls
* throwing fails because we lack async try/catch or at least with async generators we lack a performant try/catch or with bluebird-like optimizations (hacks) we lack typed catch and Error.create
The latter is far closer to a consistent error handling pattern than the former, which promises implement (poorly and verbosely IMO). Additionally, async generators also nicely address the issue of slicing your userland stack away from core, so you get a two for one.
Looks to me like you didn't even read the crashy wrapper. With it, its possible to control what gets caught and what doesn't.
Although, I would really like to see a library that is written so badly that even catching exceptions thrown in the same tick would make it unusable.
The default is fine, and exceptional cases can also be covered on demand. (The presented `using` and `acquire` functions might even let you clean up after some "non-recoverable" errors!)
Then I don't see how you can claim that the fact that "Promises coerce caught exceptions occurring on the origin tick to errors" is bad. This coerces all the invalid argument exceptions into errors. Is that bad? Or are there other errors which should not be caught but are thrown in this manner, and if so, can you provide (links to) examples which ones and why?
These should be quite rare and are addressable by wrapping that badly behaving function with a crashy wrapper that throws asynchronously...
I addressed your point and you are acknowledging it and I can see you understand it from you various other responses. Promises catch "synchronous" exceptions, however unlikely. You can optionally rethrow them / manually crash, which you would need to. Your response is also the most common response, "don't worry about them and deal with them when they come up."
I prefer to avoid this mentality and it motivates the difference in our opinions.
No, I'm just saying that undocumented inconsistency cannot be addressed in any other way other than dealing with it on a case by case basis, as it comes up.
This is not true. With promises, the wrapper of core functionality is left up to you. You can either write a crashy wrapper, an uncrashy wrapper, or a wrapper which picks whether to crash or not depending on the kind of error. I wrote more about this here [1]
Most default wrappers provided by promise libraries catch all synchronous errors but don't do anything with asynchronous errors. So far, this seems to be a fine default -- most unrecoverable, state-corrupting thrown errors in node core are asynchronous, and all the invalid argument errors are synchronous. But even if that weren't the case, it would be a simple matter to write a more specific wrapper.
[1]: https://github.com/petkaantonov/bluebird/issues/51#issuecomm...