Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Trap the error msg from Mime::Lite

by chrism01 (Friar)
on Jan 22, 2008 at 06:06 UTC ( [id://663508]=perlquestion: print w/replies, xml ) Need Help??

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

Monks
I'm using Mime::Lite to send an email (with attachment) and I'm testing the error handling.
I can force an error easily enough and it appears in the logfile, but I want to trap the text so I can send an email (via Mail::Mailer) to sysadmin.
The only problem is that the error text is not stored in $! or $@, even if I wrap an eval around the $msg->send statement.

I've tried the web ( eg http://www.perlmonks.org/?node_id=239562) and super search (eg http://www.perlmonks.org/?node_id=563095), but the (very few) examples I've found all seem to assume the error text is in fact stored in $! or $@, as did I, but it deosn't actually seem to be so.

Anyone know how I can get it?

Cheers
Chris

Replies are listed 'Best First'.
Re: Trap the error msg from Mime::Lite
by Sidhekin (Priest) on Jan 22, 2008 at 17:25 UTC

    Did someone say "trap"? Test::Trap to the rescue! :)

    The error message you want is printed on STDOUT on my machine. I was expecting STDERR. Other errors may come from the Perl code, so we want the $@ as well. My very own Test::Trap can give you all! :)

    The example below, based on your code, makes use of the :output(systemsafe) pseudo layer, new in version 0.1.0. Older versions of Test::Trap may use :flow:stderr(systemsafe):stdout(systemsafe) to much the same effect.

    #!/usr/bin/perl -w use Test::Trap qw/ :output(systemsafe) /; use MIME::Lite; # send mail attachments use Sys::Hostname; # Used to insert hostname in emails use Cwd; # Get current full dir for error msgs use strict; # Enforce declarations my ( $hostname, # name of this box for sending $prog_full_name, # prog path + name $contact_email, # contact email address $msg, # msg object $sender, # sender of email $subject, # subject line in email $body_text # actual email msg text ); # Get hostname anyway we can using Sys::Hostname; # tries syscall(SYS_gethostname), `hostname`, `uname -n` $hostname = Sys::Hostname::hostname(); # Get program full path name $prog_full_name = cwd()."/${0}"; # Set the fields required by Mailer... $contact_email = ''; $sender = "$prog_full_name"; $subject = "$prog_full_name: Asset Mgr Report"; $body_text = "This is an automated message:\n\n"; # ... and send it # Header $msg = MIME::Lite->new( From => $sender, To => $contact_email, Subject => $subject, Type =>'multipart/mixed' ); # Body Content $msg->attach( Type => 'TEXT', Data => $body_text ); # Attachment $msg->attach( Type => 'text/plain', Path => "/home/chrism/t.cvs", Filename => "t.csv", Disposition => 'attachment' ); # Send trap { $msg->send or print "Error: $@\n" }; $_ and print "Error: $_\n" for $trap->die, $trap->stdout, $trap->s +tderr;

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

      Thx,
      That seems to work.
      The only problem is that it outputs to stdout. What I need to do is capture those error(s), print a copy to stdout (which along with stderr is re-directed to my logfile) and save a copy in a variable that I can then use elsewhere.
      I'm having trouble re-arranging your code to do that (save a copy)
      Help..

      Cheers
      Chris

        What I need to do is capture those error(s), print a copy to stdout (which along with stderr is re-directed to my logfile) and save a copy in a variable that I can then use elsewhere.

        Right. I think I'd choose grep for that one. Replace my last line above with these:

        my @errors = grep { defined && length } $trap->die, $trap->stderr, $tr +ap->stdout; print "Error: $_\n" for @errors; # any and all error(s) are now left in @errors

        Update: Oh, and "logfile"? Is this for production, not just testing? Then I'd definitely get Test::Trap version 0.1.0 — it fixes, among other things, a bug that in this case might slowly fill up your /tmp partition. Oops.

        print "Just another Perl ${\(trickster and hacker)},"
        The Sidhekin proves Sidhe did it!

Re: Trap the error msg from Mime::Lite
by Gangabass (Vicar) on Jan 22, 2008 at 06:25 UTC

    Please show your code and we can help you.

      #!/usr/bin/perl -w use MIME::Lite; # send mail attachments use Sys::Hostname; # Used to insert hostname in emails use Cwd; # Get current full dir for error msgs use strict; # Enforce declarations my ( $hostname, # name of this box for sending $prog_full_name, # prog path + name $contact_email, # contact email address $msg, # msg object $sender, # sender of email $subject, # subject line in email $body_text # actual email msg text ); # Get hostname anyway we can using Sys::Hostname; # tries syscall(SYS_gethostname), `hostname`, `uname -n` $hostname = Sys::Hostname::hostname(); # Get program full path name $prog_full_name = cwd()."/${0}"; # Set the fields required by Mailer... $contact_email = ''; $sender = "$prog_full_name"; $subject = "$prog_full_name: Asset Mgr Report"; $body_text = "This is an automated message:\n\n"; # ... and send it # Header $msg = MIME::Lite->new( From => $sender, To => $contact_email, Subject => $subject, Type =>'multipart/mixed' ); # Body Content $msg->attach( Type => 'TEXT', Data => $body_text ); # Attachment $msg->attach( Type => 'text/plain', Path => "/home/chrism/t.csv", Filename => "t.csv", Disposition => 'attachment' ); # Send $msg->send or print "Error: $@\n";
      Output is:
      sendmail: fatal: No recipient addresses found in message header Error:
      where 1st line appears in logfile, 2nd line shows error text is not in $@.
      Same occurs if I use $! instead as above.

      If I try this instead

      eval{$msg->send}; print "Error: $@\n" if($@);
      I only get the logged msg. My own error msg does not appear.

        The error message

        No recipient addresses found in message header

        seems to confirm that you never set $contact_email. Did you just remove your email address from the line initializing it for privacy reasons or is the recipient really empty?

        $contact_email = 'chrism01@example.com';

        would be an example of initializing the email address. Of course, you would possibly use a local email address instead of an address that is routed through the internet.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://663508]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-04-18 20:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found