in reply to style for returning errors from subroutines

For this last idea, I'd pass the whole $ERR hashref to the fatal_error function. Up to the function to decide, based on configuration variables (possibly, a --debug command-line option), whether to print something on STDERR, send a email or whatever.

Besides that, have you considered using the exception handling mechanism? Run the code that can cause an error within an eval {} construct. The code in question will simply die should anything go amiss, with a usefull error message or error code. After the eval, you just test whether $@ is true and handle the error depending on its value. e.g.

eval { # format_output or get_user may die $formatted_users = format_output(get_users($fh)); } if ( $@ ) { # test the value of $@ to know what's been going on. die $@ }

This approach let you separate in distinct blocs the actual code (eval { ... }) and the error handling (if ( $@ ) { ... }).

UPDATE: of course, you still need to come up with a convention about the contents and format of $@.

UPDATE: When testing the value of $@, you can of course choose not to die, but send an email, come up with a reasonable default for the value that failed just to be created, or do whatever you care to handle the error. If you can't figure out what happened by testing on $@, then die $@ so that the error is caught at an upper level, where it might become fatal.

HTH

--bwana147

Replies are listed 'Best First'.
Re: Re: style for returning errors from subroutines
by Boldra (Curate) on Jun 14, 2001 at 20:55 UTC
    My gut feeling when I read this was that there was going to be a pretty serious impact on program speed; but assuming my Benchmarking isn't totally silly, there is no significant efficiency loss:
    use strict; use Benchmark; timethese(100000, { 'Using Eval' => 'eval { &test or die }; $@ and warn("maths +sux:$@");', 'using or' => '(&test) or warn("maths sux:$@");', }); sub test { #A test which always returns true for(1..100) {($_>0) || return 0} return 1; } boldra@trinity:~/workspace$ ./eval_test.pl Benchmark: timing 100000 iterations of Using Eval, using or... Using Eval: 10 wallclock secs ( 6.46 usr + 0.06 sys = 6.52 CPU) using or: 10 wallclock secs ( 6.28 usr + 0.11 sys = 6.39 CPU)
    It does, however, look pretty messy to (IMHO) do this for every subroutine call, and it doesn't allow me to put non-fatal errors in my subroutines.