kk2202 has asked for the wisdom of the Perl Monks concerning the following question:


Hi,
I am a newbie, have to fix an issue in existing perl scripts.Kindly assist me with the following.

FileA has a subroutine "funcA" funcA invokes a subroutine "funcB" in another file "FileB".

Now inside funcB in FileB, there is an error due to which it exits from the there. (exit 1 had been used).

Now how do I know about this in funcA. Please note that I can not use "return" in funcB. That is a very big subroutine and changing exit to return -1 or so creates other issues.

Is there a way or any variable that I can check in funcA in FileA that might indicate me that funcB has exited with error.

FileA sub funcA{ funcB(); //how to check if funcB has returned due to "exit 1" } FileB sub funcB{ ........... ........... ........... if () exit 1; ........... ........... }

Replies are listed 'Best First'.
Re: Subroutine to indicate error condition
by moritz (Cardinal) on Oct 15, 2009 at 07:22 UTC

    exit is not appropriate for handling error conditions, you should throw an exception instead. Please see Dealing with errors in subroutines for more discussion on this subject.

    Perl 6 - links to (nearly) everything that is Perl 6.
Re: Subroutine to indicate error condition
by Marshall (Canon) on Oct 15, 2009 at 08:35 UTC
    If you mean that some Perl function in module A (in say FileA.pm or main program) calls some sub, funcB() in Perl module B(in FileB.pm or even within main program module) and this funcB() does an exit(1)...There is nothing to be "done" about it, exit(x) returns a status code to the OS and the Perl program stops. Your funcA() will never see this exit(1) value.

    It sounds to me like you should replace say "exit(1);" with die "some error message";. "die" prints an error message to STDERR and then the Perl program stops. If the "die" statement's string does not end in a \n, then Perl will report module and line number when "death occured". Normally this is of no interest to the user if the error message is good enough. But sounds like this tid-bit will help you debug a problem (extra info good for you).

    The "normal" convention for a program to exit when it completes successfully is exit(0) or exit(with a non zero value) if program "bombed". That value (8 bits) is reported to the shell that invoked the program. I don't think that you want to mess around with starting a shell program that starts your Perl script and checks the return code.

    Instead of exit(1), in Perl use: die "some error". Throwing exceptions has to do with OO stuff and OO is probably not what you have here in the legacy code. Do a search for the exit() lines and replace with 'die "error msg"' lines.

Re: Subroutine to indicate error condition
by cdarke (Prior) on Oct 15, 2009 at 08:16 UTC
    moritz is right, of course, that a module or subroutine should not use exit (unless specifically designed for that purpose), maybe you are stuck with some code that someone else wrote? You can detect an exit by using an END block, for example:
    # gash.pm package gash; use warnings; use strict; sub gashsub { print "In gashsub\n"; exit 1; } END { print __PACKAGE__." is exiting $?\n"; } 1; # main.pl #!/usr/bin/perl use warnings; use strict ; use gash; gash::gashsub(); END { print __PACKAGE__." is exiting $?\n"; }
    Produces the output:
    In gashsub main is exiting 1 gash is exiting 1
    The exit value is in $?.

    Subroutines should ideally use die, which can then be trapped using eval.