Uncaught exception

Swift Mailer is a fantastic library for sending email with php. Discuss this library or ask any questions about it here.

Moderators: Chris Corbyn, General Moderators

Post Reply
robsch
Forum Newbie
Posts: 3
Joined: Sat Sep 22, 2007 3:01 pm

Uncaught exception

Post by robsch »

Hi. I'm using Swift 3.3.1 and PHP 5.2.2. When I try to send email via swift I get a strange error:

Code: Select all

Warning: fclose(): 35 is not a valid stream resource in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 384

Warning: fclose(): 35 is not a valid stream resource in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 384

Fatal error: Ignoring exception from Swift_Connection_SMTP::__destruct() while an exception is already active (Uncaught Swift_Connection_Exception in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 386) in /usr/lib/php/swift/Swift.php on line 233
This is the code snippet that is responsible for the error Message:

Code: Select all

<?php
require_once "swift/Swift.php";
require_once "swift/Swift/Connection/SMTP.php";

try {
        $swift_text =& new Swift(new Swift_Connection_SMTP("localhost", 25));
}
catch (Exception $e) {
        die( $e->getMessage());
}
?>
Probably something is wrong with my server configuration, but I can't figure out what.
roscoe
Forum Commoner
Posts: 85
Joined: Tue Aug 05, 2003 10:24 am
Location: essex uk

Post by roscoe »

your path to swift may be incorrect :wink:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

roscoe wrote:your path to swift may be incorrect :wink:
That's not the problem since the error comes from Swift/Connection/SMTP.php and relates to a method in there ;)

It looks like what's happening is:

1. "new" Swift() throws an exception that the connection fails to starts
2. Your try/catch picks it up
3. The garbage collector runs the conection's __destruct() method at an inconvenient time (inside the catch() block)
4. Boom, fatal error.

I'm not sure whether to class that as a PHP flaw or a flaw on my account. It's not possible to predict when __destruct() will run so by the same token I don't think it would be possible to wrap try/catch around it, unless perhaps such code appears *inside* the destructor.

I'll try modifying my code and see if it corrects the problem, unless you wanted to try your hand at it?

Inside Swift/Connection/SMTP.php find __destruct() and change it to:

Code: Select all

public function __destruct()
{
  try {
    //everything that's already in the method goes here
  } catch (Exception $e) {}
}
robsch
Forum Newbie
Posts: 3
Joined: Sat Sep 22, 2007 3:01 pm

Post by robsch »

I modified the destructor as you suggested,

Code: Select all

public function __destruct()
  {
    try {
         $this->stop();
    } catch (Exception $e) {
        die($e->getMessage());
    }
  }
but now I get this error:
Warning: fclose(): 35 is not a valid stream resource in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 384
The SMTP connection could not be closed for an unknown reason. (fsockopen: #0)
Warning: fclose(): 35 is not a valid stream resource in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 384
The SMTP connection could not be closed for an unknown reason. (fsockopen: #0)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

robsch wrote:I modified the destructor as you suggested,

Code: Select all

public function __destruct()
  {
    try {
         $this->stop();
    } catch (Exception $e) {
        die($e->getMessage());
    }
  }
but now I get this error:
Warning: fclose(): 35 is not a valid stream resource in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 384
The SMTP connection could not be closed for an unknown reason. (fsockopen: #0)
Warning: fclose(): 35 is not a valid stream resource in /usr/lib/php/swift/Swift/Connection/SMTP.php on line 384
The SMTP connection could not be closed for an unknown reason. (fsockopen: #0)
Why have you got a die() in there?
robsch
Forum Newbie
Posts: 3
Joined: Sat Sep 22, 2007 3:01 pm

Post by robsch »

I wanted to stop the program as soon as the exception is thrown. It doesn't make much difference when changing it to "print", then the same error shows up more often.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

robsch wrote:I wanted to stop the program as soon as the exception is thrown. It doesn't make much difference when changing it to "print", then the same error shows up more often.
The whole point of the try/catch was to "hide" the error, not to display it ;) Because the error is occuring during script shutdown (__destruct()) in this particular unusual scenario it makes sense to deal with errors transparently. I'll be changing the destructor to look like I posted myself.

EDIT | Just to clarify, even though you would be hiding the error from __destruct() your outer try/catch() wrapped arround "new Swift()" should still catch the exception which was thrown during connection startup. The original problem you posted is caused by an unusual combination of circumstances which is what I'm trying to address now.
dataj1998
Forum Newbie
Posts: 1
Joined: Tue Dec 18, 2007 11:27 am

Post by dataj1998 »

Hi Chris,

I'm a coworker of robsch and tried to figure out the problem more in detail :) [it didn't last 3 months, but we had to do other work]

I tried to "debug" the constructor and followed the path down to following problem:
If I make a

Code: Select all

var_dump($this->connection);
inside the Swift.php and the functions that are called during construction I get down to the point, that the stream changes to "UNKNOWN" after calling

Code: Select all

$this->handshake($greeting)
at line 220, Swift.php.

And now some more astonishing things happen:
I added

Code: Select all

var_dump($this->connection); var_dump($this->connection);
right before line 220 (more or less as an accident ;)) and woha:
First Output of var_dump:

Code: Select all

object(Swift_Connection_SMTP)#9 (12) {
  ["handle:protected"]=>
  resource(37) of type (stream)
  ["port:protected"]=>
  int(25)
  ["encryption:protected"]=>
  int(8)
  ["timeout:protected"]=>
  int(15)
  ["username:protected"]=>
  bool(false)
  ["password:protected"]=>
  bool(false)
  ["authenticators:protected"]=>
  array(0) {
  }
  ["errno:protected"]=>
  int(0)
  ["errstr:protected"]=>
  string(0) ""
  ["extensions:protected"]=>
  array(0) {
  }
  ["isESMTP:protected"]=>
  bool(false)
  ["server"]=>
  string(9) "localhost"
}
Second Output of var_dump:

Code: Select all

object(Swift_Connection_SMTP)#9 (12) {
  ["handle:protected"]=>
  resource(37) of type (Unknown)
  ["port:protected"]=>
  int(25)
  ["encryption:protected"]=>
  int(8)
  ["timeout:protected"]=>
  int(15)
  ["username:protected"]=>
  bool(false)
  ["password:protected"]=>
  bool(false)
  ["authenticators:protected"]=>
  array(0) {
  }
  ["errno:protected"]=>
  int(0)
  ["errstr:protected"]=>
  string(0) ""
  ["extensions:protected"]=>
  array(0) {
  }
  ["isESMTP:protected"]=>
  bool(false)
  ["server"]=>
  string(9) "localhost"
}
So how can it be, that a variable changes during two directly following dumps? (you see, the handle is firstly a stream, than unknown)

It turns out to me, that there are two possibilies:
- PHP 5.2.2 is broken here :twisted:
or
- our selfcompiled PHP suffers a module or something at the configuration files

I tested on other servers with PHP 5.1.2 and 5.2.3 and our Code does what it should... Maybe I should set up another server with 5.2.2 and test it there (the server were it should run is a live system)

I've also sent a mail "by hand" over an SMTP connection without calling the Swift constructor (made an Connection Object, called start() and afterwards used write on the Connection) - that works...

And last but not least: I used the PHP4 Version of SwiftMailer with the PHP5 on our Server and - IT WORKS!

It would be very nice, if you have a guess, a tip or even a litte straw for me/us :)

thx a lot
Post Reply