Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Trap the error msg from Mime::Lite

by chrism01 (Friar)
on Jan 22, 2008 at 06:06 UTC ( #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

Comment on Trap the error msg from Mime::Lite
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
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? | Other CB clients
Other Users?
Others chanting in the Monastery: (10)
As of 2015-07-30 08:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (270 votes), past polls