Re: chain of exceptions, next method
On Wednesday, March 6, 2024 6:06:34 AM MST kdevel via Digitalmars-d-learn wrote: > On Saturday, 10 September 2022 at 08:48:39 UTC, Andrej Mitrovic > > wrote: > > [...] > > I wish the compiler would rewrite scope(failure) to use chained > > exceptions. Otherwise any exceptions thrown within > > scope(failure) can end up losing information about what was the > > original exception that was thrown. > > Ran into this issue with the following ordering bug: > > auto tmpfilename = fn.dup ~ ".XX\0"; > int fd = mkstemp (tmpfilename.ptr); > scope (failure) remove (tmpfilename); // bug: > if (fd == -1) >throw new Exception (strerror(errno).to!string); > > The error thrown was > > Failed to remove file ... > > Is there any work in progress to chain the exceptions in > scope(failure)? If anything, I think that it's been decided that chained exceptions were a mistake. So, if things go in any direction with them, it's likely to be towards removing them, not doing more to support them. - Jonathan M Davis
Re: chain of exceptions, next method
On Saturday, 10 September 2022 at 08:48:39 UTC, Andrej Mitrovic wrote: [...] I wish the compiler would rewrite scope(failure) to use chained exceptions. Otherwise any exceptions thrown within scope(failure) can end up losing information about what was the original exception that was thrown. Ran into this issue with the following ordering bug: auto tmpfilename = fn.dup ~ ".XX\0"; int fd = mkstemp (tmpfilename.ptr); scope (failure) remove (tmpfilename); // bug: if (fd == -1) throw new Exception (strerror(errno).to!string); The error thrown was Failed to remove file ... Is there any work in progress to chain the exceptions in scope(failure)?
Re: chain of exceptions, next method
On Sunday, 14 August 2022 at 02:30:43 UTC, Paul Backus wrote: On Sunday, 14 August 2022 at 02:07:05 UTC, Ali Çehreli wrote: This automatic "combining" of exceptions happens for cleanup code like scope(exit). (I remember bug(s) for scope(failure).): To be precise, an exception thrown inside a 'finally' block gets chained onto the previous exception, but an exception thrown inside a 'catch' block does not. scope(exit) and scope(failure) are just syntax sugar for 'finally' and 'catch', respectively. I wish the compiler would rewrite scope(failure) to use chained exceptions. Otherwise any exceptions thrown within scope(failure) can end up losing information about what was the original exception that was thrown.
Re: chain of exceptions, next method
On Sunday, 14 August 2022 at 02:07:05 UTC, Ali Çehreli wrote: This automatic "combining" of exceptions happens for cleanup code like scope(exit). (I remember bug(s) for scope(failure).): To be precise, an exception thrown inside a 'finally' block gets chained onto the previous exception, but an exception thrown inside a 'catch' block does not. scope(exit) and scope(failure) are just syntax sugar for 'finally' and 'catch', respectively. Relevant spec paragraph: If an exception is raised in the FinallyStatement and is not caught before the original exception is caught, it is chained to the previous exception via the next member of Throwable. Note that, in contrast to most other programming languages, the new exception does not replace the original exception. Instead, later exceptions are regarded as 'collateral damage' caused by the first exception. The original exception must be caught, and this results in the capture of the entire chain. Source: https://dlang.org/spec/statement.html#try-statement So, once an exception is caught, the chain ends, and any exception thrown after that begins a new chain.
Re: chain of exceptions, next method
On 8/13/22 15:59, kdevel wrote: > Quote from `src/druntime/src`: > > ``` > /** > * Returns: > * A reference to the _next error in the list. This is used when a new > * $(D Throwable) is thrown from inside a $(D catch) block. The > originally > * caught $(D Exception) will be chained to the new $(D Throwable) > via this > * field. > */ > @property inout(Throwable) next() @safe inout return scope pure > nothrow @nogc { return nextInChain; } > > ``` This automatic "combining" of exceptions happens for cleanup code like scope(exit). (I remember bug(s) for scope(failure).): import std.stdio; void foo() { // Bug? Should work for scope(failure) as well. scope (exit) { bar(); } throw new Exception("from foo"); } void bar() { throw new Exception("from bar"); } void main() { try { foo(); } catch (Exception exc) { for (Throwable e = exc; e; e = e.next) { writeln(e.msg); } } } The output: from foo from bar You can do the same by calling chainTogether(). Here is an excerpt from an old experiment of mine: try { foo(); } catch (Throwable exc) { Throwable.chainTogether(exc, new Exception(" ... ")); throw exc; } Ali