Subject: | Original references + stack trace when non-object references are thrown |
For non-references:
# trapping
% perl -d:Confess -MData::Dump -E'sub f { die "Not found" }; eval { f }; dd $@'
"Not found at -e line 1.\n\tmain::f() called at -e line 1\n\teval {...} called at -e line 1\n"
# rethrowing
% perl -d:Confess -MData::Dump -E'sub f { die "Not found" }; eval { f }; die'
Not found at -e line 1.
main::f() called at -e line 1
eval {...} called at -e line 1
...propagated at -e line 1.
For non-object references:
# trapping (the original reference is returned, but no stack trace information)
% perl -d:Confess -MData::Dump -E'sub f { die [404,"Not found"] }; eval { f }; dd $@'
[404, "Not found"]
% perl -d:Confess -MData::Dump -E'sub f { die [404,"Not found"] }; eval { f }; die'
ARRAY(0xb6f160) at -e line 1.
Is there a way to get both the stack trace and the original reference, so I can rethrow and still retain the original stack trace? Perhaps by wrapping the exception using on object (I see from the source code that Devel::Confess already does this kind of trick, albeit only for objects?). Imagined interface:
# trapping (the original reference is returned, but no stack trace information)
% perl -d:Confess=wrap_ref -MData::Dump -E'sub f { die [404,"Not found"] }; eval { f }; dd $@'
bless({message>[400, "Not found"], stack_trace=>...}, "Devel::Confess::Wrapper")
# rethrow
% perl -d:Confess=wrap_ref -MData::Dump -E'sub f { die [404,"Not found"] }; eval { f }; die'
ARRAY(0xb6f160) at -e line 1.
main::f() called at -e line 1
eval {...} called at -e line 1
...propagated at -e line 1.
# rethrow after formatting the message
% perl -d:Confess=wrap_ref -MData::Dump -E'sub f { die [404,"Not found"] }; eval { f }; $err = $@; $err->message = "<color>ERROR ".$err->message->[0].": ".$err->message->[1]."</color>"; die $err'
"<color>ERROR 404: Not found</color>" at -e line 1.
main::f() called at -e line 1
eval {...} called at -e line 1
...propagated at -e line 1.
Or do you think this use-case is too specific? Admittedly, I've very seldom encountered other people's code where it uses non-object refs as exception. I use this technique myself in my CLI framework (Perinci::CmdLine::Lite).
Regards,
perlancar