Java also has chained exceptions, done manually
Neia Neutuladh
neia at ikeran.org
Thu Sep 6 17:13:52 UTC 2018
On Thursday, 6 September 2018 at 14:39:12 UTC, Andrei
Alexandrescu wrote:
> First off, there's no tree of exceptions simply because... well
> it's not there. There is on field "next", not two fields "left"
> and "right". It's a linear list, not a tree. During
> construction there might be the situation whereby two lists
> need to be merged. But they will be merged by necessity into a
> singly-linked list, not a tree, because we have no structural
> representation of a tree.
The runtime appends any exception raised by a `scope
(exit|failure)` statement to the next list of an exception
already being raised. So if I write:
scope (exit) throw new Exception("scope 1");
scope (exit) throw new Exception("scope 2");
throw new Exception("primary");
I get output like:
object.Exception at scratch.d(21): primary
----------------
??:? void scratch.throwy() [0x53a74c01]
??:? _Dmain [0x53a74d68]
object.Exception at scratch.d(26): scope 2
----------------
??:? void scratch.throwy() [0x53a74ce1]
??:? _Dmain [0x53a74d68]
object.Exception at scratch.d(25): scope 1
----------------
??:? void scratch.throwy() [0x53a74d42]
??:? _Dmain [0x53a74d68]
Okay, that seems reasonable. But what if each of those
`scope(exit)` statements had their own chains?
scope (exit) throw new Exception("scope 1", new Exception("cause
1"));
scope (exit) throw new Exception("scope 2", new Exception("cause
2"));
throw new Exception("primary");
object.Exception at scratch.d(8): primary
----------------
??:? void scratch.throwy() [0x7259caf3]
??:? _Dmain [0x7259cc64]
object.Exception at scratch.d(7): scope 2
----------------
??:? void scratch.throwy() [0x7259cba5]
??:? _Dmain [0x7259cc64]
object.Exception at scratch.d(7): cause 2
object.Exception at scratch.d(6): scope 1
----------------
??:? void scratch.throwy() [0x7259cc4c]
??:? _Dmain [0x7259cc64]
object.Exception at scratch.d(6): cause 1
The actual structure of the exceptions: `primary` has children
`scope 2` and `scope 1`; `scope 2` has child `cause 2`; `scope 1`
has child `cause 1`. A tree.
The encoded structure: a linked list where only the first two
positions have any structure-related meaning and the rest are
just a sort of mish-mash.
This isn't a situation you get in Java because Java doesn't have
a way to enqueue multiple independent actions at the end of the
same block. You just have try/finally and try(closeable).
> (As an aside, it does seem we could allow some weird cases
> where people rethrow some exception down the chain, thus
> creating loops. Hopefully that's handled properly.)
Not if you semi-manually create the loop:
auto e = new Exception("root");
scope (exit) throw new Exception("scope 1", e);
throw e;
Filed as https://issues.dlang.org/show_bug.cgi?id=19231
More information about the Digitalmars-d
mailing list