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