Re: chain of exceptions, next method

2024-03-06 Thread Jonathan M Davis via Digitalmars-d-learn
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

2024-03-06 Thread kdevel via Digitalmars-d-learn
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

2022-09-10 Thread Andrej Mitrovic via Digitalmars-d-learn

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

2022-08-13 Thread Paul Backus via Digitalmars-d-learn

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

2022-08-13 Thread Ali Çehreli via Digitalmars-d-learn

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