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

I've spent alot of time googling and supersearching but haven't made much progress with this problem. I'd appreciate any feedback, references, etc. I'm using Archive::Tar to create and read tape header files on my Solaris 8 box (Perl 5.8, Archive::Tar 1.07). I started out using backtics w/gtar, but decided I'd might get better error handling using a Perl module.

Following the examples in the module documentation I arrived at the following:

use strict; use warnings; use Archive::Tar; my $device = '/dev/rmt/1'; my $tar = Archive::Tar->new(); warn $tar->error unless $tar->read($device); my $header_file = 'tape.header'; my @files = Archive::Tar->list_archive($device); my $junk = $tar->get_content($header_file) or die "### ERROR - No such file in archive: '$header_file'\n\n" +; __OUTPUT__ Warning: something's wrong at test.errors.pl line 7. No such file in archive: 'tape.header' at test.errors.pl line 11 ### ERROR - No such file in archive: 'tape.header'
The results bother me for three reasons:
  1. What's with the warning, is it an indicator that I'm trying to use tar->error in a way that it shouldn't be?
  2. Is it normal for Archive::Tar to burp warning messages ("No such . . .)? Shouldn't it just return warning/error codes and rely on the programmer to handle them?
  3. The first message is a Perl warning, not an Archive::Tar warning. I googled on "Warning: something's wrong at" and found an interesting but unrelated Re: "Database handle destroyed" quirks
As for #2 above, I know I can use $Archive::Tar::WARN = 0; but the module docs advise against it. Has anyone else experienced these problems and what can I do to eliminate them?

Thanks

Replies are listed 'Best First'.
Re: Archive::Tar and error handling
by BrowserUk (Patriarch) on Oct 25, 2003 at 19:01 UTC

    The warning "Something's wrong" is coming from the line

    warn $tar->error unless $tar->read($device);

    And indicates that whilst $tar->read( $device ) is returning false, the return value from $tar->error is undefined or null.

    Whilst it may be considered "bad form" for a module to return and error, but fail to set it's error message, the module is free and if that means that the author hasn't crossed all the I's and dotted all the T's, it is still pretty good value for money:)

    In this case, it probably means that the module was unable to open or read from the device. It is possible that you might get a little more information as to the cause if you were to check $! to see what, if any, system error was logged. It would be prudent to set $! = 0 before the failing call so that you aren't confused by a previous, unrelated error.

    Exactly which is difficult to tell from a simple visual examination of the code. However, you have the code and the device. Maybe it time to learn to perl -d and step through the code until you can see where the error is being returned without an error message having been set. When you work out where the failure to set an error message is occuring, you can a) fix that ommission in your copy, b) send a suggestion to the author that he amends the module in a similar way.

    The authors recommendation that you leave warnings enabled is only that, a recommendation. If you wish to handle the errors yourself internally, then set $Archive::Tar::WARN = 0;, the author won't hold it against you:)


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

      I pretty much knew where the problem was and what causes it initially. The program works as expected as long as there is a tar archive as file #1 on the tape. The problem is that I have to make sure that the tape in the drive is the correct one. So I need error handling graceful enough so that the program doesn't generate cron mailings every time it runs.

      As you suggest, I can turn off the Archive::Tar warnings and don't need to use $tar->error since $! returns 'I/O error' and will probably serve for most of the other errors I might encounter. Rewritten as follows should meet my needs for now:

      use strict; use warnings; use Archive::Tar; $Archive::Tar::WARN = 0; my $device = '/dev/rmt/1'; my $tar = Archive::Tar->new(); $! = 0; $tar->read($device); die "### ERROR on \$tar->read($device): $!\n\n" if $!;

      I'll test this further and post my findings if I have to modify the approach further. Thanks for the suggestions, they were very helpful. I'm still very disppointed with the error handling capabilities of this module.

Re: Archive::Tar and error handling
by liz (Monsignor) on Oct 25, 2003 at 18:07 UTC
    Don't know about the rest, but the "Something's wrong" message is simply from a warn with an empty string or without a string at all:
    $ perl -e 'warn' Warning: something's wrong at -e line 1. $ perl -e 'warn $a' Warning: something's wrong at -e line 1.

    Liz

Re: Archive::Tar and error handling
by b10m (Vicar) on Oct 25, 2003 at 19:06 UTC

    1. `perldoc -f warn`:

           
    warn LIST
    
    Produces a message on STDERR just like "die", but
    doesn't exit or throw an exception.
    
    If LIST is empty and $@ already contains a value
    (typically from a previous eval) that value is
    used after appending "\t...caught" to $@.  This is
    useful for staying almost, but not entirely simi-
    lar to "die".
    
    If $@ is empty then the string "Warning: Some-
    thing's wrong" is used.
    
    2. I think that warning can be blamed on "use warnings;"

    --
    B10m

      I'll investigate #1 above and the suggestions by demerphq but I'd already tried commenting out "use warnings;". It produces the message in either case (even with $Archive::Tar::WARN = 0;).
Re: Archive::Tar and error handling
by Anonymous Monk on Oct 25, 2003 at 22:25 UTC
    I'm quite interested to find out /where/ exactly the problem occurs...
    from reading your code, i'd expect things to break in the $fh->open call in Archive::Tar::_get_handle() -- which should log an error.

    The fact it doesn't would lead me to believe that the open call returns true, but the filehandle isn't actually opened, which seems really bizarre.

    Please mail me at kaneatcpan.org and we'll try to figure out what goes wrong here :)

    --Kane