develooper Front page | perl.perl5.porters | Postings from July 2020

Re: Exceptions thrown from LEAVE

Thread Previous | Thread Next
From:
Christian Millour
Date:
July 7, 2020 18:43
Subject:
Re: Exceptions thrown from LEAVE
Message ID:
37effd0d-4a3c-6a2a-477c-a934f839d6c4@abtela.com
Le 07/07/2020 à 18:24, Paul "LeoNerd" Evans a écrit :
> Further discussions about LEAVE have lead to an interesting question -
> What is the behaviour of exceptions thrown from them?
> 
> In a simple case such as
> 
>    sub f {
>      return "123";
>      LEAVE { die "456" }
>    }
> 
> It is relatively easy to argue the case that this should die with
> "456 at ...", but complications come when the LEAVE block is being
> executed during stack unwind because another exception is being thrown.
> 
>    sub g {
>      die "123";
>      LEAVE { die "456" }
>    }
> 
> It is fairly agreeable that invoking g() should die in some manner,
> but exactly how?
> 
> Taking a look around other things: Within perl we have many CPAN
> variations on this theme, almost all of which ultimately rely on
> DESTROY methods being invoked on objects captured by block-scoped
> variables. Because exceptions during DESTROY are turned into warnings,
> necessarily all of these must act the same way. Thus the 456 would be
> warned about but otherwise invisible to callers, who would receive the
> 123 exception.
> 
> My own Syntax::Keyword::Try offers a similar feature in the form of
> try/finally blocks. These use the core SAVEDESTRUCTOR_X feature which
> could be capable of propagating the exception but chooses not to due to
> some unanswered questions I have about how that would be represented.
> 
> Some other languages choose different ideas. For example, Java takes
> the latest exception and totally discards an earlier one
> (https://programming.guide/java/try-finally.html). Python appears to do
> similar, judging from some StackOverflow posts (though at present I am
> unable to locate specific words in the actual spec). Suggestions are
> that C# and JavaScript also do this.
> 
> In the case of the 123+456 case above, I can basically see three
> possible choices of behaviour:
> 
>    a) Warn about 456, and propagate 123 to caller.
> 
>       This is the current behaviour of SKT's try/finally, and also
>       equivalent to how other CPAN options work)
> 
>    b) Warn about 123, and propagate 456 to caller.
> 
>       This is what most other langs do, except they don't even have a
>       mechanism to warn about 123, so all information about 123 is lost
>       entirely!
> 
>    c) Combine 123 and 456 into a new "double fault" exception
>       representation
> 
>       This one would not be possible without a more standard form in
>       which to represent exceptions in core perl. But see also
>          https://github.com/Perl/perl5/issues/17951
> 
> 
> This also posted to github at
>    https://github.com/Perl/perl5/issues/17949#issuecomment-654976025
> 

variants on c). I would love a stack of exceptions, or linked 
exceptions, to tell me e.g. "weeeell, your original problem was a 
timeout on accessing such and such web resource; then your failed to 
remotely log that error because, duh, you seem to be out of network; 
then your fallback logger also failed because it looks like you have 
exceeded your disk quota".

Not a realistic example but you get the idea.

You would need a way to access this stack/history in a catch block, and 
maybe to cook it if you dealt with some of the reported issues but have 
to rethrow the exception (with its cooked history) to another agent up 
the ladder to deal with the rest. System support would be needed for 
error raised in system destructors (e.g. automatic closing of lexical 
filehandles).

I have no clue as to whether this is doable, even with an EV. Might be 
nice though.

--Christian

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About