1

I have some code in a __destruct() method that sometimes throws an exception. The __destruct() method is being called during another exception and I'm seeing a vague error:

PHP Fatal error:  Ignoring exception from exampleClass::__destruct() while an exception is already active

which is hiding the actual exception that's being called. I'd like to do something like:

public function __destruct() 
{
  try
  {
    // do work here
  }
  catch(Exception $e)
  {
    // check if we're already in an exception and log it
    if(already_in_exception())
    {
      error_log($e->getMessage());
    }
    // normal destruct, re-throw
    else
    {
      throw $e;
    }
  } 
}

Bonus points if it's PHP 5.1.6 compatible!

Thank you in advanced!

Gary Richardson
  • 16,081
  • 10
  • 53
  • 48
  • It would be better to avoid throwing exceptions in destructors. Why does your destructor need to throw an exception? Maybe we can figure out how to avoid that. C++ specific, but: http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor – Corbin Sep 08 '11 at 00:01
  • I don't see why an exception would prevent another handler from correctly running... It might be best to handle the exception previous to letting another occur? – Zoey Sep 08 '11 at 00:02
  • 4
    I also fail to see the need to throw exceptions out of a destructor. Can you show a more concrete example? – NullUserException Sep 08 '11 at 00:03
  • In my particular case, the destructor is calling a PDO->rollBack(). I don't want to always log the error at that level as there are other times when I want the PDOException to bubble up to the next level. – Gary Richardson Sep 08 '11 at 00:07
  • 2
    Over simplifying quite a bit, but in general, mission critical code should not be in a destuctor. Basically, the logic of "if this situation happens, roll back" should not be in the destructor. Where specifically it should be depends. The only time (well, not only... I hate absolutes) you should do anything in a desctructor that can throw an exception is if you're willing to ignore that exception (in the sense of not letting it propagate out of the dtor). – Corbin Sep 08 '11 at 00:12
  • @Gary Any chance you could implement a cleanup function, manually called before destruction, that implements this functionality? – Zoey Sep 08 '11 at 00:13
  • The rollback is not mission critical.. The object has a commit() function that is called when a commit is required. The default behaviour is to not commit unless requessted -- this isn't an error condition. The rollback is there to close out the pending transaction and free up any locked resources. – Gary Richardson Sep 08 '11 at 17:02

1 Answers1

1

Your problem isn't because you're throwing an exception from within another, it's because you're throwing an exception from a destructor.

From php.net: http://php.net/manual/en/language.oop5.decon.php I quote:

"NOTE: Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error."

Rethink your logic abit and do this prior to deconstruction.

smassey
  • 5,875
  • 24
  • 37