Results 1 to 10 of 10

Thread: discovering real errors in perl?

  1. #1
    Senior Member roswell1329's Avatar
    Join Date
    Jan 2002
    Posts
    670

    discovering real errors in perl?

    Howdy all --

    In response to an article I read in Sys Admin Magazine (a damn good publication, for anyone out there who hasn't found it yet) I've been trying to create a template perl script that has all the functionality I usually want in a production-grade script that I can use to rollout new scripts much faster. I'm just about done, but I'm having some difficulty trying to discover if my script is ending out with errors or not. I've got an END block that defines what to do when everything is done, or if the script happens to die unexpectedly. Here's what I have for this check at the end:

    Code:
    if(($!) || ($?))  {
      my $mesg = "Internal Failures:\n------------------\n$!\n\n" .
        "External Failures:\n-----------------\n$?\n"; 
      &mail_errors($mesg);
    }
    I'm really just checking to see if the $! or the $? variables contain anything (and if they do, create a mail message, and send it out), but I'm discovering that the $! variable seems to ALWAYS contain something. Does anyone know of a better way to see if a perl script is ending gracefully or not?
    /* You are not expected to understand this. */

  2. #2
    Just Another Geek
    Join Date
    Jul 2002
    Location
    Rotterdam, Netherlands
    Posts
    3,401
    I usually do something like:

    if sometest==fault myerror_routine;

    sub myerror_routine {

    die "This is the error: $@";

    }

    From Perlvar:

    $EVAL_ERROR
    $@ The Perl syntax error message from the last eval()
    operator. If $@ is the null string, the last
    eval() parsed and executed correctly (although the
    operations you invoked may have failed in the nor-
    mal fashion). (Mnemonic: Where was the syntax
    error "at"?)

    Warning messages are not collected in this vari-
    able. You can, however, set up a routine to pro-
    cess warnings by setting $SIG{__WARN__} as
    described below.

    Also see "Error Indicators".
    Oliver's Law:
    Experience is something you don't get until just after you need it.

  3. #3
    Senior Member roswell1329's Avatar
    Join Date
    Jan 2002
    Posts
    670
    That's a good idea. Thanks!
    /* You are not expected to understand this. */

  4. #4
    Jaded Network Admin nebulus200's Avatar
    Join Date
    Jun 2002
    Posts
    1,356
    Isn't perl extremely ticky (like shell) about the $? and $! variables ? Ie, just by doing another check after the error, it can cause $? and $! to be over-written with the success value of the check you just ran ? Anyway, I think that is what I was always told and why, if I was going to do an error message, copied the value of $! to something else and sent it to a generic error reporting function (similar to what SirDice mentioned)...
    There is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect...There is no escape from it, we are forever slaves to it. Our only hope, our only peace is to understand it, to understand the 'why'. 'Why' is what separates us from them, you from me. 'Why' is the only real social power, without it you are powerless.

    (Merovingian - Matrix Reloaded)

  5. #5
    Leftie Linux Lover the_JinX's Avatar
    Join Date
    Nov 2001
    Location
    Beverwijk Netherlands
    Posts
    2,534
    I don't use perl much (at all)

    But I do think you've got it right there, nebulus200..

    I remember having a little thinko in one of my bash scripts where indeed the $? didn't mean what I expected it to mean..
    ASCII stupid question, get a stupid ANSI.
    When in Russia, pet a PETSCII.

    Get your ass over to SLAYRadio the best station for C64 Remixes !

  6. #6
    Senior Member roswell1329's Avatar
    Join Date
    Jan 2002
    Posts
    670
    Originally posted here by nebulus200
    Isn't perl extremely ticky (like shell) about the $? and $! variables ? Ie, just by doing another check after the error, it can cause $? and $! to be over-written with the success value of the check you just ran ? Anyway, I think that is what I was always told and why, if I was going to do an error message, copied the value of $! to something else and sent it to a generic error reporting function (similar to what SirDice mentioned)...
    Indeed, that seems to be what I'm finding. The $! and $? variables are unreliable at best. Does anyone know of a better way of detecting in the END block how the script is exiting? Specifically, I want to check if the script is dieing or not, but everything should be going through END.
    /* You are not expected to understand this. */

  7. #7
    Jaded Network Admin nebulus200's Avatar
    Join Date
    Jun 2002
    Posts
    1,356
    I would have to see what it is you are doing to recommend a way to make it work...perhaps you shouldn't tell it to die if you really want it to go to the end ? If you are really wanting to check return codes from the execution of the script ( I assume you are calling it from something else ), you could always use exit (#) instead and just change # to be whatever number 1..255 that you want (I think its limited to 255, not sure) ... Your other script could then do a mapping of # --> message to determine error codes... but like I said, depends on what/how you are doing things to whether that would work cleanly or not...

    If you really do want to the script to execute to the end even on error, then there are several different ways to accomplish that ...

    There is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect...There is no escape from it, we are forever slaves to it. Our only hope, our only peace is to understand it, to understand the 'why'. 'Why' is what separates us from them, you from me. 'Why' is the only real social power, without it you are powerless.

    (Merovingian - Matrix Reloaded)

  8. #8
    Senior Member roswell1329's Avatar
    Join Date
    Jan 2002
    Posts
    670
    Okay, here's the whole story:

    I work as a sysadmin in a LARGE environment of HP-UX, Solaris, and Linux (around 900 systems). I'm creating a template script that my team and I can use to quickly implement scripts for that environment while having much of the groundwork already laid. One problem I have is that the only version of Perl that I can guarantee will be on every system is version 5.005, and I can only use the standard modules that come with that version. (Yeah, it sucks.) Here's what I have so far for this script:

    http://www.m00k.net/template.txt.

    I'm only dying at a few points in the script where I feel it's critical to halt execution -- if the config file exists but cannot be read, for example, or the logfile cannot be opened, or someone throws an INT signal. I've included an END{} block that will close the script gracefully -- even in the event of of an interrupt or a die, but I cannot seem to find a good way of detecting how I get to the END block.

    Perhaps I need to do more with the $ex_status variable I'm using.

    I just tried doing this:

    Code:
    open(THING,"/no/such/file") or ($ex_status = 1 && die "Cannot open file");
    That didn't work. Any way you can think of to accomplish something like this?
    /* You are not expected to understand this. */

  9. #9
    Jaded Network Admin nebulus200's Avatar
    Join Date
    Jun 2002
    Posts
    1,356
    Rather than doing the die, you might try using exit with unique return codes, especially since you are already basically looking at it anyway...for example:

    Code:
    open(CONFIG,"$cfgfile") 
        or die "Cannot open config file $cfgfile\n";
    to
    Code:
    open(CONFIG, "$cfgfile") || exit(3);
    Then the $! should have a 3 in it...which you could then use to stand for Cannot open config file...

    Another way to approach it is to have a generic cleanup function...for example...

    Code:
    open(CONFIG, "$cfgfile") || &cleanup($!, "Failed to open config file", 3);
    
    sub cleanup($$$)
    {
    <error checking on args skipped>
        print @_[1] . "(" . @_[0] . ")\n";
    <any other code cleanup, like closing open file handles>
    exit(@_[2]);
    }
    Which I would expect to produce a printout (to console, you can change that) of:

    Failed to open config file (O/S specifc error message)

    The script would then exit with an error code of 3 which other scripts could read and know to mean a special exit condition occurred...
    There is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect...There is no escape from it, we are forever slaves to it. Our only hope, our only peace is to understand it, to understand the 'why'. 'Why' is what separates us from them, you from me. 'Why' is the only real social power, without it you are powerless.

    (Merovingian - Matrix Reloaded)

  10. #10
    Senior Member roswell1329's Avatar
    Join Date
    Jan 2002
    Posts
    670
    Excellent! This is what I was looking for. Many, many thanks, nebulus200 for your help. It is much appreciated!
    /* You are not expected to understand this. */

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •