Thread overview
Observing exceptions in a destructor
Apr 22, 2015
Mark Isaacson
Apr 22, 2015
ketmar
Apr 22, 2015
Jonathan M Davis
Apr 22, 2015
Mark Isaacson
April 22, 2015
I'd like to be able to know if my destructor is being called because an exception was thrown. Any way to do that?

I tried this: http://ideone.com/JbXH2w

(Pasted here for convenience):

import std.stdio, std.exception;

struct Catcher {
	~this() {
		try {} catch (Exception e) {
			writeln("Woooo!");
			throw e;
		}
		scope (failure) {
			writeln("Woooo woooo!");
		}
		writeln("Destructing...");
	}
}

void main() {
	scope (failure) writeln("Sensible");
	scope (exit) writeln("Always written");
	Catcher c1;
	scope auto c2 = Catcher();
	throw new Exception("Foobar");
}

Which does not print the "Wooo" lines, but does print all the others.
April 22, 2015
On Wed, 22 Apr 2015 01:02:15 +0000, Mark Isaacson wrote:

> I'd like to be able to know if my destructor is being called because an exception was thrown. Any way to do that?

sorry, you can't.

April 22, 2015
On Wednesday, April 22, 2015 01:02:15 Mark Isaacson via Digitalmars-d-learn wrote:
> I'd like to be able to know if my destructor is being called because an exception was thrown. Any way to do that?
>
> I tried this: http://ideone.com/JbXH2w
>
> (Pasted here for convenience):
>
> import std.stdio, std.exception;
>
> struct Catcher {
>   ~this() {
>       try {} catch (Exception e) {
>           writeln("Woooo!");
>           throw e;
>       }
>       scope (failure) {
>           writeln("Woooo woooo!");
>       }
>       writeln("Destructing...");
>   }
> }
>
> void main() {
>   scope (failure) writeln("Sensible");
>   scope (exit) writeln("Always written");
>   Catcher c1;
>   scope auto c2 = Catcher();
>   throw new Exception("Foobar");
> }
>
> Which does not print the "Wooo" lines, but does print all the others.

The exception isn't being thrown in the destructor, so there's no exception to catch. It's more like

catch(Exception e)
{
    call_destructor_on_c1();
    throw e;
}

AFAIK, there is no way to detect whether a destructor is being called because of an exception being thrown.

Why would you need to know anyway? Just for debugging purposes? I can't think of any case where it would matter.

- Jonathan M Davis

April 22, 2015
Oh well :(.

Yeah, it's just for debugging. I want to publish a script that
automatically gathers relevant debug information so that my users
can just copy paste it all into one place, ready for me to take a
look even if I can't repro. One of the primitives in my script is
a wrapper around std.process that caches the result, and I wanted
to make it so that if the program throws an exception while one
of the CacheResult objects is in scope, it dumps its contents out
to a pastebin and logs the URL.

I ended up manually adding some scope (failure)s at the call
sites and putting the relevant code in a member function... but
it would have been nice to not need to duplicate the scope
(failure)s and have it simply live in the destructor.