Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

How to handle Errors?

by Scarborough (Hermit)
on Apr 05, 2004 at 16:27 UTC ( [id://342669] : perlquestion . print w/replies, xml ) Need Help??

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

I am about to start work on a project which requires a lot of error handling and am keen to keep all error code in one place maybe an error module or develop my own error object
Or better still someone might point me in the direction of some error handling tutorial/module or a really good explanation of perls own error handling.
Thanks for your help as usual.

Replies are listed 'Best First'.
Re: How to handle Errors?
by dragonchild (Archbishop) on Apr 05, 2004 at 16:43 UTC
    The canonical way to handle errors in Perl is to use die and eval. You throw your errors using die and catch them using the block form of eval. You can even throw objects with die and catch them with eval, for fine-grained handling. There are many examples in the various manuals.

    Do NOT use Error, because it can cause memory leaks in a number of situations.

    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Re: How to handle Errors?
by Tomte (Priest) on Apr 05, 2004 at 16:48 UTC

    For an explanation/overview of existing modules, see CPAN search-results for Error

    Being far from a thourough explanation of the concepts, a search on point to a few interesting locations in the docs.

    Keep us posted on your searchresults elsewhere, it's IMHO an interesting topic...


    Hlade's Law:

    If you have a difficult task, give it to a lazy person --
    they will find an easier way to do it.

Re: How to handle Errors?
by McMahon (Chaplain) on Apr 05, 2004 at 16:49 UTC
    Good for you for thinking ahead! (I test software for a living, we appreciate people who write good error handling.)

    The sort-of-classical way to to do this is:

    Make sure each subroutine (or object) returns a particular code depending on whether it completed properly or had a particular error.
    Check the completion code in the main body of the program as each sub or object completes its work. If it is an error code, call the error-handling sub or object.
    In the error-handling routine, re-use as many error codes as possible: for instance, error 42 could be "file $var not found". The error handling code would report "file critical.file not found in subroutine foo." or something like that.

    Note that I believe Perl will do a lot of this for you, if you check for exceptions at sane places in the code.

    If you get a first pass at error-handling, I'd like to encourage you to post it here, because I'd like to see what you come up with.
Re: How to handle Errors?
by matija (Priest) on Apr 05, 2004 at 16:56 UTC
    Error handling in Perl follows the maxim that there is more than one way to do it.

    For starters, there is the simple "do or die" syntax known from such "phrases" as

    open(....) or die "Could not open ... $!\n";
    (there is also a variant a variant called warn which sends the same output to STDERR, but doesn't terminate the program.

    Some modules deliver errors in parameters (i.e. returning 0 from a particular subroutine), others die.

    Some (like DBI with it's RaiseError/PrintError can do either or both.

    There are several modules that install their own handlers for die/warn, the most used is probably CGI::Carp which shows the error messages on the browser screen instead of in the web server's error log.

    If you want to handle errors differently, in a java-ish, object oriented way, you might want to check out Error. It implements the try/catch method of error handling.

Re: Errors
by adrianh (Chancellor) on Apr 05, 2004 at 19:35 UTC
•Re: How to handle Errors?
by merlyn (Sage) on Apr 05, 2004 at 19:54 UTC
      Class::Exception to create the nested error classes,

      Exception::Class... m'thinks :-) (which I agree is very nice)

      and Error to create syntax to catch exceptions.

      I have to admit I shun the syntactic sugar and just use plain old if statements. Avoids the whole accidentally-creating-closures issue / memory leak issues.

Re: How to handle Errors?
by Elijah (Hermit) on Apr 05, 2004 at 19:25 UTC
    Well error handling for your specific project will be just that, specific to your project. The scenerios you may or may not run into in this particular app will be most likely assosiated to the app therefore an error module probably would be a bad idea.

    Write a module for a common task or event you plan on using across numerous projects and that would apply to numerous projects. In my opinion error handling does not fall into that category.

    The main thing you should do with seeting up your logic flow for your project is handle ALL errors first in each situation. If you are envoking @ARGV at the command line then parse all command line args first and handle every possible error that could happen at command line (like typos or missing arguments) and then if all args pass then handle the obviously correct input (due to passing your error handling) accordingly.


    #!/usr/bin/perl -w use strict; # Error checking! die "Required argument missing!\n" unless ($#ARGV > 0); # This along with the following code ensures a positive numeric range. my $last = 0; # More Error handling! for (@ARGV) { # Ensures numeric input! die "Argument \"$_\" is not numeric!\n" unless (/\d+/); # Ensures a negative number was not entered as first argument and # also that the second argument is higher in value then the first. die "Invalid range!\n" unless ($_ > $last); $last = $_; } # Here we know that there was some sort of input at command line. # We also know that each argument is numeric. # We also know that the user gave a valid range in order for the app # to print out a consecutively increasing numeric count. # So with all the error handling passed if the program gets to this po +int. # we know we have the required VALID command line input in order for u +s to # successfully run this program. for ($ARGV[0] .. $ARGV[1]) { print; print"\n"; }