On 21/11/2019 09:58, Mathias Gaunard wrote:
In any case catching and rethrowing exceptions at every layer to add context information as it bubbles up is not really an idiom I would recommend. Not only is quite ugly and complexifies control flow, it's also inefficient and leads to a poor experience when debugging.
I think it works reasonably well, without too much ugliness. It's a bit better in the .NET languages, since they adopted the idea of nested exceptions from the start -- at each catch site, you can choose whether to add additional details to the existing exception and rethrow it (although this is rarely done since it typically isn't visible in the string output), to throw another exception with the original nested within (most common), or to throw another exception without the original (rarer, but occasionally appropriate). While C++ now has the ability to do nested exceptions as well, the plumbing required to actually deal with them (and to extract and log information) is still pretty terrible. And most existing code will neither nest exceptions nor unpack them. Granted, it can be a little annoying to debug if you have it set to break on all exceptions (rather than just uncaught ones), but even so, exceptions should be rare and following it up the call chain can be useful in itself, so it's not all that poor an experience. Usually the only time exceptions cause a poor debugging experience is when code is using them incorrectly (as control flow, not for exceptional cases; which often leads to try-catch-ignore anti-patterns).
It is a better idea to use normal control flow for this.
How would you use normal control flow for that example? (Failure to parse at a low level that doesn't know the filename, and the higher level does know the filename.)