4 ms·
Correct me if I'm wrong but isn't a big part of async programming that it forces you to think about error handling. Working as a Java developer I have seen very
by zongitsrinzler 13y ago
Correct me if I'm wrong but isn't a big part of async programming that it forces you to think about error handling.
Working as a Java developer I have seen very lousy error handling mostly because try/catch lets you wrap everything and kill errors easily.
Most of the node code I have seen handles errors much better thanks to it's async nature.
- gruseom 13y agoIf you do it well, you can get very precise error handling, because errors are detected in the context where they first occur. However, to do it well you have to put a try/catch around every asynchronous operation, which makes nested callbacks even harder to read than they already are. Consequently people write code that doesn't handle all possible errors, and when one falls between the cracks, it gets caught only by the top-level default handler (assuming you've declared one), at which point the context is lost. The other problem that comes up is the difficulty of getting a backtrace beyond the current callback. It can be hard to troubleshoot an error in a callback when you can't look back at how the async call got started. In such cases what you really want is a list of backtraces that capture all the relevant history. I seem to recall that people have come up with solutions for this, but can't remember what they are. Maybe someone else can comment?
- zongitsrinzler 13y agoI think this is a good point, sometimes you don't need too precise error handling, then try/catch is very good.
- tg3 13y agoMost Node.js I've seen doesn't make extensive use of Javascript's built-in exception handling, and instead relies on the convention of the first parameter of a callback being an Error object if one occurred (so no try/catch, which doesn't catch async errors anyway). The stack trace is a pain for those operations, and any error that occurs as part of "normal" javascript operation (e.g. ReferenceError) has to be handled like a normal exception, which makes the style inconsistent and therefore a bit harder to manage. I think that the latest or upcoming version of Node is presenting a solution to this in the form of domains, but I'm not too familiar with it.
- gruseom 13y agoThe first-parameter convention only works for application errors and errors from libraries that also follow the convention. Everything else, including the JS runtime, throws exceptions whether we like it or not. So either you have to make sure that your code never triggers any of those—which is a pretty tall order—or put try/catches around everything, even if your own code doesn't throw any exceptions. That's more than a bit harder to manage—if you do it correctly, there are so many try-catch blocks that the rest of the code almost gets drowned out by them. In my observation, most people deal with this by sacrificing a certain amount of error safety in order to make the code more tractable. It seems like the kind of problem that is better dealt with by a compiler.
- aaronyo 13y agoPromises help with this quite a lot. http://promises-aplus.github.io/promises-spec/ http://promises-aplus.github.io/promises-spec/ What 3.2.6.2 means is that any thrown exception is caught and turned into a rejected promise which will bubble up (across async boundaries) until it gets to a rejection handler. I haven't had too much experience with Domains, but I believe they are generally used for courser grain error handling (because it's a bit verbose to attach them all over the place). E.g., to catch most errors (it's no guarantee what 3p libs do to your context) generated in fulfillment of a particular web request.
- gruseom 13y agoCan promises guarantee that condition with only library code? or do you still have to have try/catch in the application code, and if so where? Also, do any of the promises libraries solve the backtrace problem, and if so how do they do it?
- tg3 13y agoUnfortunately putting a try/catch around a 3p lib doesn't actually capture exceptions generated by those libs (unless they occur before any async operations, which I would say is the exception rather than the rule). You're right that you have to manage exceptions, which is difficult. The biggest problem I've had with Node is the runtime exceptions that crash the entire process because they go uncaught. To deal with that, I have the server automatically restart on failure - far from an ideal scenario of error recovery (and what I think you're referring to when you talk about sacrificing error safety).