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

I'm getting some strange errors from perl with regards to a Mail::Sender scirpt:

Command died with status 40: "/usr/local/apache/cgi-bin/include/email.pl". Command output: prin +t() on closed filehandle Symbol::GEN0 at /usr/lib/perl5/site_perl/5.6.0/Mail/Sender.pm line 1451. print() o +n closed filehandle Symbol::GEN0 at /usr/lib/perl5/site_perl/5.6.0/Mail/Sen +der.pm line 1907. readline() on closed filehandle Symbol::GEN0 at /usr/lib/perl5/site_perl/5.6.0/Mail/Sender.pm line 109. print() on + closed filehandle Symbol::GEN0 at /usr/lib/perl5/site_perl/5.6.0/Mail/Sen +der.pm line 126. readline() on closed filehandle Symbol::GEN0 at /usr/lib/perl5/site_perl/5.6.0/Mail/Sender.pm line 109. Can't use +an undefined value as a symbol reference at /usr/lib/perl5/site_perl/5.6.0/Mail/Sender.pm line 1451. Issuing r +ollback() for database handle being DESTROY'd without explicit disconnect().

Sender is installed and works properly with other scripts. The script I'm trying to run is quite long so I'll post some pieces:

beginning.... 1 #!/usr/bin/perl -w 2 3 ################### 4 #parts of the script are from the perldesk email.pl file 5 #the rest are my own modifications 6 #Neil Watson Mon Aug 12 10:17:47 EDT 2002 7 ################## 8 9 #scalars from these includes 10 use vars qw($dbhost $dbname $dbuser $dbpass $ticketad $hdtime) +; 11 12 require "/usr/local/apache/cgi-bin/include/conf.pl"; 13 require "/usr/local/apache/cgi-bin/include/lang/en.inc"; 14 15 my ($user, $callemail, $status, $category, $ownership); 16 my ($staffemail, @staffemail, $callid); 17 my ($ref, %global, $sender); 18 19 use strict; 20 use warnings; 21 22 ############## 23 #parse incoming support email 24 ############## 25 26 use MIME::Parser; 27 use MIME::Entity; 28 use MIME::Body; 29 use Mail::Sender; 30 First sender: 60 #if subject is emplty, send reply and stop here 61 if ((!$subject) || ($subject eq "")){ 62 63 $sender = new Mail::Sender; 64 65 $sender->Open({ 66 smtp =>'mail', 67 to =>"$from", 68 from =>"$ticketad", 69 fake_from =>"$ticketad", 70 subject =>"Help Desk Response", 71 headers => "Errors-To: postmaster\@mydomain.com"}); 72 73 $sender->Body; 74 $sender->SendEnc(<<'*END*'); 75 Please resend your request with a subject line intact, if you +are replying to a staff response, please keep the subject line intact for tracking purposes, if this is a new request, please give +it a suitable subject line. 76 77 Thank You, 78 Customer Support 79 *END* 80 $sender->Close; 81 exit; 82 } Sender later on 183 if ($callemail != $from) { 184 185 $sender = new Mail::Sender; 186 187 $sender->Open({ 188 smtp =>'mail', 189 to =>"$from", 190 from =>"$ticketad", 191 fake_from =>"$ticketad", 192 subject =>"Help Desk Submission", 193 headers => "Errors-To: postmaster\@mydomain.com"}) +; 194 195 $sender->Body; 196 $sender->SendEnc(<<'*END*'); 197 Sorry, you seem to have sent this help desk response to a call + which is not owned by you. If you believe this to be a mistake, plea se check that you are sending this response from the email add +ress used when logging this call. 198 199 Thank You, 200 Customer Support. 201 *END* 202 $sender->Close; 203 $dbh->disconnect(); 204 exit; 205 }

Any suggestions would be appreciated.

Neil Watson
watson-wilson.ca

Replies are listed 'Best First'.
Re: Mail::Sender error
by derby (Abbot) on Aug 15, 2002 at 18:46 UTC
    Hmmm ... not sure but why don't you check for errors

    $sender->Open( ... ) or die "Error: $Mail::Sender::Error\n";

    I always wrap stuff like this (Mail::Mailer) in one sub (or local package) that dies on error and then I just eval the call.

    sub mymail { my( $to, $text ) = @_; eval { Local::Mail::send( $to, $text ); }; warn "Errors: $@\n" if $@; }

    and then in the Local::Mail::send method would just be a wrapper for Mail::Sender that dies on any error.

    -derby

    updateI just perused the source of Mail::Sender and noticed that an exit value of 40 is SERVNOTAVAIL (and it closes the socket which explains the rest of your error messages). Moral: check for errors and act appropriately.

      updateI just perused the source of Mail::Sender and noticed that an exit value of 40 is SERVNOTAVAIL (and it closes the socket which explains the rest of your error messages). Moral: check for errors and act appropriately.

      I'm sorry, can you explain that?

      Neil Watson
      watson-wilson.ca

        Sure, in a nutshell, there's an issue with the mail server and its not available (SERVNOTAVAIL). Mail::Sender is noticing the unavailabilty, setting an error code, and then closing the socket to the server.

        At its heart Mail::Sender uses SMTP. The protocol is quite simplistic (hence the S) and returns a code with each reply.

        The author has decided to reduce the myriad of 4xx and 5xx STMP error replies to a single SERVNOTAVAIL message. In addition, if for some reason he cannot read from the socket (lost connection, crashed machine), he flags that as SERVNOTAVAIL too.

        This is one of the disadvantages of using SMTP directly as opposed to an MTA (mail transfer agent) like sendmail. If you drop an email into an MTA, it may try to send the email several times for you. When using STMP directly, you have to decide what to do (drop them to the floor, queue them up for another go-round, etc).

        -derby

        Mail::Sender is generating an error message because it could not connect to the server. Because you are not checking for errors, you would never know that and your code continues anyway. A quick perusal of the Mail::Sender doc suggests some error checking techniques. Something to the effect of:
        $sender->Open({ smtp =>'mail', to =>"$from", from =>"$ticketad", fake_from =>"$ticketad", subject =>"Help Desk Submission", headers => "Errors-To: postmaster\@mydomain.com"}); die "Error: $Mail::Sender::Error\n" unless ref $sender;
        -- vek --