On 9/7/18 7:15 PM, Tobias Mueller wrote:
On Thursday, 6 September 2018 at 14:39:12 UTC, Andrei Alexandrescu wrote:
Second, it does pay to keep abreast other languages. I had no idea
(and am quite ashamed of it) that Java also has chained exceptions:
https://www.geeksforgeeks.org/chained-exceptions-java/
Now I'm surprised... is there a language (except C++) that supports
exceptions that does _not_ have it?
Java: getCause()
C#: InnerException
PHP: getPrevious()
...
David Nadlinger wrote that Python also has them.
I think chained exception in D is semantically very different from other
languages like Java.
In languages like Java or C# the exception chain has nothing to do with
saving exceptions that are thrown in finally blocks.
Instead the chain is used for a layer model. The "outer" exception is
the higher level exception and the "inner" exception is the lower level
cause of the higher level exception.
Often a low level exception is quite meaningless when thrown over
multiple levels in the call stack.
For example, imagine a program that uses a configuration file. While
parsing the configuration, a misformatted number is encountered.
If the NumberFormatException is propagated to the top level, it is
basically useless for programmatic error handling.
This is much better:
ConfigurationException -> JsonParsingException -> NumberFormatException
The higher level exceptions are therefore directly caused by the lower
level exception and always thrown _directly_ in the catch block where
the lower level exception is catched and readily available. Not in a
finally block and not indirectly in a function called from the catch block.
Manually passing the inner exception to the constructor of the outer
exception is trivial and IMO the right thing, because it's probably not
always wanted.
Now in D, chained exceptions work differently.
The first exception that is thrown is deemed the "important" exception
and later exceptions are simply chained to it. A direct semantic
connection between the exceptions is not possible at all, since the
later exception has no knowledge about the first exception at all.
It also means that the order of the exceptions is reversed. The first
exception is the "outer" exception which is the exact opposite of how it
is meant in Java.
When handling an exception, it's not clear at all what those additional
exceptions mean and how they should be handled.
Personally I find the Java/C# model much more useful.
Well indeed the upper you are on the stack, the more likely you are in a
high-level function. It's a good heuristic. Sadly we cannot change
chaining semantics now, but it does stand to reason to print the last
exception in a chain, instead of the head, as the most relevant cause.
Guess we'd do good to have such functionality in the stdlib.
Andrei