I have written a perl program which internally calls three perl modules. My supervisor after reviewing the code asked me add global exception handling. I didn't understand what he meant by this. He also said use Eval to accomplish this.I am not sure how to use Eval so that it catches any exception in the enire perl module. Can anyone help me by providing links or by providing explanation? Thanks in advance.
-
1This might help: [What is the best way to handle exceptions in Perl?](http://stackoverflow.com/questions/4006267/what-is-the-best-way-to-handle-exceptions-in-perl) – Amadan Feb 29 '16 at 07:14
-
4I think you'll probably have to ask your supervisor! As far as I'm concerned, global exception handling in Perl involves writing a `die` handler by assigning a subroutine to `$SIG{__DIE__}` (as described in [perlvar](http://perldoc.perl.org/perlvar.html#General-Variables)). And it's something that's really only good for debugging. On the other hand, `eval` allows you to handle errors in only one block of the code. I guess if you had a `main()` subroutine that executed the whole program, like in C, then you could put that in an `eval { main(); }` block, but I'm not sure I see the point. – Borodin Feb 29 '16 at 07:43
-
You got great advice and information from [Amadan](http://stackoverflow.com/users/240443/amadan) and [Borodin](http://stackoverflow.com/users/622310/borodin), whose comment also expresses the fact that it is not quite clear what your situation is; "global exception handling" is a strange term to me. Here are a few questions: How much/often do you call functions from those modules? At what level -- buried deep inside subs or in `main::`? What are the modules? What is the size and structure of the whole project? In a nutshell, I mean. – zdim Feb 29 '16 at 08:42
-
It's a pretty small project consisting of around 400 lines of code. What my supervisor needs is - totally I have 4 programs (one main program and three sub modules which are called from main). For each program he wants me to have an exception handling where in if something goes wrong it will be highlighted and it becomes easy for us to debug. – nithin Feb 29 '16 at 09:34
-
@nithin: But that already happens. If your code encounters a fatal error then it dies with a message giving the reason, as well as the source file and line number being executed at the time. Your supervisor has clearly flummoxed me and many other Stack Overflow subscribers, as you have had no answers so far at all. Are they asking for a stack backtrace? It may not be enough to know where in the code the failure occurred because the cause is ultimately due to wrong parameters being passed to a subroutine. Ask your supervisor for an *example* of an error and the information they would like – Borodin Feb 29 '16 at 15:17
2 Answers
For each program he wants me to have an exception handling where in if something goes wrong it will be highlighted and it becomes easy for us to debug.
When an uncaught exception occurs, it is printed to STDERR. Your highlighting requirement is already being met.
Exceptions messages already include the line number at which they were thrown (unless specifically suppressed), so some information to help debug is already available.
$ perl -e'sub f { die "bar" } f("foo")'
bar at -e line 1.
Adding use Carp::Always;
to your scripts will cause a stack backtrace to be provided as well, providing more information.
$ perl -e'use Carp::Always; sub f { die "bar" } f("foo")'
bar at -e line 1.
main::f("foo") called at -e line 1

- 367,544
- 15
- 269
- 518
The problem you are given seems imprecise. "Global" and eval
are somewhat contradictory, as
Borodin explained in his comment. Another way to do things "global" is given in ikegami's answer. However, since mentioning eval
is specific here is a rundown on a very basic use of that.
You use eval
on a block of code (or an expression but that is not what you want here). If a die
is thrown anywhere inside that block, the eval
catches that in the sense that you get the control back, the program won't just die. The variable $@
gets filled with the error message. Then you can interrogate what happened, print out diagnostics, and possibly recover from the error.
eval { run_some_code(@args) };
if ($@) {
carp "Error in `run_some_code()`: $@ --";
# Do further investigation, print, recover ...
}
You can have any code in the eval
block above, it needn't be a single function call. Note that eval
itself returns values that convey what happened (aside from $@
being set).
As for the "global" in your problem statement, one thing that comes to mind is that you use eval
at the level of main::
-- wrap in it any subs that themselves invoke functions from the modules.
A crucial thing about exceptions is that they "bubble up". When a die
(Perl's sole exception) is thrown in a sub and the caller doesn't eval
it, it goes up the call chain ... eventually showing up in main::
, and if it is not caught (eval
-ed) there then the program dies. So you can eval
the top-level call in main::
and get to know whether anything anywhere below went wrong.
eval { top_level_call(); };
if ($@) {
warn "Error from somewhere in `top_level_call(): $@";
}
# Functions
sub top_level_call {
# doing some work ...
another_sub();
# doing more ...
}
sub another_sub {
# do work, no eval checks
}
If an error triggering a die
happens in another_sub()
its processing stops immediately and the control is returned to the caller, the top_level_call()
. Since that sub doesn't check (no eval
there) its execution stops at that point as well, and the control returns to its caller (in this example the main::
itself). So it eventually hits main::
, and eval
-ing there lets you know about errors and your program won't just exit.
Perhaps that's what was meant by "global" exception handling using eval
.
You can do far more along these lines, if this is what you need to be doing. See eval for starters. Update your question with clarifications, so you get more discussion here.
In practical terms, I would say that you equip yourself with some understanding of eval
use as well as some of "global" error reporting, and then ask your supervisor for clarification and/or examples, as suggested by Borodin.