in reply to try catch getting ignored by SIG DIE subroutine

Appreciate insight on why if I have a defined SIG{__DIE__}, it is overriding a try/catch block?

It doesn't override it - you are, by calling exit inside the handler. You don't need to do that, since $SIG{__DIE__} gets called when the program is dieing anyway. If I remove the exit and leave the rest of the code unchanged, I get the output:

DIE ERROR: malformed JSON string, neither array, object, number, strin +g or atom, at character offset 0 (before "(end of string)") at 120991 +8.pl line 26. : Error decoding data from data1

Which is hopefully getting a bit closer to what you want. As for the special variables, I think you've got a couple of things mixed up:

I really need the SIG_DIE functionality for the rest of the code, just not have it get int he way in the try/catch section

If you really don't want the handler to be called inside a try/catch, you can temporarily disable it like Athanasius suggested, although personally I would do it with local, that is: try { local $SIG{__DIE__} = 'DEFAULT'; ... (no other changes needed). It's also possible to use $^S, like Corion suggested, to customize the behavior of the handler based on whether it's inside an eval or not, for example by sticking die @_ if $^S; at the very beginning - although make sure to read all of the documentation, for example %SIG strongly cautions against using $^S!

Now, as for the custom exit code, it seems that unfortunately you can't set $? from within a $SIG{__DIE__} handler - although you can set it from inside an END block. Although I don't consider this the most elegant solution, something like this might be closer to what you want:

{ # block to hide $_exitcode from rest of program my $_exitcode; $SIG{__DIE__} = sub { die @_ if $^S; # don't run this handler from inside "eval" my $err = shift; chomp($err); print STDERR "DIE ERROR: $err\n"; $_exitcode = 2; }; END { $?=$_exitcode if defined $_exitcode } }

In any case, all of this seems like you're doing some relatively complicated error handling - I suggest you read all of the documentation I've linked above. Also, I would encourage considering if such complex error handling is necessary in the first place - if you could give some more background, like why you need all this (especially the custom exit code), and how you expect your program to behave exactly in the face of different errors, what kind of errors you are expecting, etc., perhaps we can suggest a better overall solution.

Update: As ikegami pointed out, $! is in fact related to the exit code, I was wrong above. And as it turns out, you can set it from inside the handler, which significantly simplifies the above code:

$SIG{__DIE__} = sub { die @_ if $^S; # don't run this handler from inside "eval" my $err = shift; chomp($err); print STDERR "DIE ERROR: $err\n"; $! = 2; };

Although if, as you said in the reply, you want to temporarily disable the handler with local $SIG{__DIE__} = 'DEFAULT';, you can remove the die @_ if $^S; (I think that's probably better). If I use this handler in your original code (and I fix the $@/$_ mixup), I get the following output, without the "DIE ERROR:" message, which I think is what you wanted?

Error decoding data from data1 malformed JSON string, neither array, o +bject, number, string or atom, at character offset 0 (before "(end of + string)") at 1209918.pl line 25.

Replies are listed 'Best First'.
Re^2: try catch getting ignored by SIG DIE subroutine
by ikegami (Patriarch) on Feb 26, 2018 at 05:18 UTC

    $! doesn't have anything to do with the exit status of the program

    An uncaught exception results in exit($! || $? >> 8 || 255).

Re^2: try catch getting ignored by SIG DIE subroutine
by dkhosla1 (Sexton) on Feb 25, 2018 at 20:16 UTC

    Thanks for the insight and the various options:

    - Thanks for the $@ vs. $_ in Try::Tiny. It was right there in first example in the docs and somehow missed it!

    - The __DIE__ & __WARN__ handling is a lot more complex in the real code. This is in a common library used bu a lot of apps. This code snippet was with some minimal lines. 'die' is being called all over the code to fill some special logs with formatted messages and some other processing, code setting etc. before exiting. Maybe, as recommended, I can clean it up a little and make it simpler. Will review the docs some more. I had struggled with the exit ($?) from __DIE__ vs. regular exit in the END block. Thanks for the clarification. The $_exitcode type solution will help.

    - Looks like the example from Athanasius is what I can safely try for now with your 'local' enhancement. Seems cleaner.