# Destructors will not be called after an exception is caught?

- Thread: https://externals.io/message/12005
- Original archive: https://news-web.php.net/php.internals/12005
- Started by Noel Forbes on 2004-08-08T14:17:47+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #12005 — Noel Forbes — 2004-08-08T14:17:47+00:00

URL: https://externals.io/message/12005#12005

Hello all,

You'll have to excuse my ignorance if something like this has already 
been posted.

In my process of writing complicated-for-the-sake-of-complicated scripts 
(:D), I came across a very strange error:

Fatal error: Exception thrown without a stack frame in Unknown on line 0

What was happening was that an Exception was being thrown in a class, 
which in turn was caught by this (in psuedo-code):

try {
	load_classes();
}
catch (Exception $e) {
	echo $e;
}

After the exception was caught and had been successfully printed to the 
screen, the above fatal error occured. The cause of this error was a 
__destruct() method in another class. Since the catch had killed the 
script, the destructor was not able to execute, as far as I can tell.

I've confirmed this on PHP 5.0.0 on FreeBSD and PHP 5.0.0 RC3 on Win32. 
Is this error message appropriate? Should this even be happening at all?

Any replies are welcomed.

Regards,
Noel Forbes

---

## #12024 — Marcus Boerger — 2004-08-09T05:28:10+00:00

URL: https://externals.io/message/12005#12024 · In reply to: #12005

Hello Noel,

i suppose one of your destructors did throw an exception. But you didn't
get any output from it. Try either 5.0.0-dev or 5.1.0-dev where the
shutdown order wasaddressed again. A reproducing script would be this:

php -r 'class t{function __destruct(){throw new exception(__METHOD__);}}$o=new t;'

regards
marcus

Sunday, August 8, 2004, 4:17:47 PM, you wrote:

> Hello all,

> You'll have to excuse my ignorance if something like this has already 
> been posted.

> In my process of writing complicated-for-the-sake-of-complicated scripts 
> (:D), I came across a very strange error:

> Fatal error: Exception thrown without a stack frame in Unknown on line 0

> What was happening was that an Exception was being thrown in a class, 
> which in turn was caught by this (in psuedo-code):

> try {
> 	load_classes();
> }
> catch (Exception $e) {
> 	echo $e;
> }

> After the exception was caught and had been successfully printed to the 
> screen, the above fatal error occured. The cause of this error was a 
> __destruct() method in another class. Since the catch had killed the 
> script, the destructor was not able to execute, as far as I can tell.

> I've confirmed this on PHP 5.0.0 on FreeBSD and PHP 5.0.0 RC3 on Win32. 
> Is this error message appropriate? Should this even be happening at all?

> Any replies are welcomed.

> Regards,
> Noel Forbes




-- 
Best regards,
 Marcus                            mailto:helly@php.net

---

## #12037 — Noel Forbes — 2004-08-09T11:43:49+00:00

URL: https://externals.io/message/12005#12037 · In reply to: #12024

Hey Marcus,

Although your script did work, it appears that the exception doesn't 
even need to be thrown in the destructor of a class, but rather anywhere 
as long as there is a destructor in any instantiated class.  Here's a 
code snippet:

    public function create($host, $port, $protocol = 'tcp', $timeout = 30) {
       
        $connString = '' . $protocol . '://' . $host . ':' . $port . '';
        $conn = @stream_socket_client($connString, $connErrorNumber, 
$connErrorString, $timeout);
        if(!$conn) {
            throw new ConnectionException($connErrorString, 
ConnectionException::E_CONNECT);
        }
       
        $controller = Controller::getInstance();
        $controller->setAttribute('conn', $conn);
       
    }

And the destructor causing the error:

    public function __destruct() {
       
        $controller = Controller::getInstance();
        $controller->removeAttribute('connObject');
       
    }

Note that these are in two different classes altogether.

I'm trying the latest 5.1.0 snap now, let's hope it works! ;)

Noel

Marcus Boerger wrote:

>Hello Noel,
>
>i suppose one of your destructors did throw an exception. But you didn't
>get any output from it. Try either 5.0.0-dev or 5.1.0-dev where the
>shutdown order wasaddressed again. A reproducing script would be this:
>
>php -r 'class t{function __destruct(){throw new exception(__METHOD__);}}$o=new t;'
>
>regards
>marcus
>
>Sunday, August 8, 2004, 4:17:47 PM, you wrote:
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]
>
>  
>
> > […]

---

## #12042 — Marcus Boerger — 2004-08-09T18:30:34+00:00

URL: https://externals.io/message/12005#12042 · In reply to: #12037

Hello Noel,

my code snippet only illustrates that an exception without a stackframe is
an exception not thrown during normal script execution. E.g. this happens
when code is executed during shutdown. This can normally only happen drom
other destructors or from some global error handling.

regards
marcus

Monday, August 9, 2004, 1:43:49 PM, you wrote:

> Hey Marcus,

> Although your script did work, it appears that the exception doesn't 
> even need to be thrown in the destructor of a class, but rather anywhere 
> as long as there is a destructor in any instantiated class.  Here's a 
> code snippet:

>     public function create($host, $port, $protocol = 'tcp', $timeout = 30) {
       
>         $connString = '' . $protocol . '://' . $host . ':' . $port . '';
>         $conn = @stream_socket_client($connString, $connErrorNumber, 
> $connErrorString, $timeout);
>         if(!$conn) {
>             throw new ConnectionException($connErrorString, 
> ConnectionException::E_CONNECT);
>         }
       
>         $controller = Controller::getInstance();
>         $controller->setAttribute('conn', $conn);
       
>     }

> And the destructor causing the error:

>     public function __destruct() {
       
>         $controller = Controller::getInstance();
>         $controller->removeAttribute('connObject');
       
>     }

> Note that these are in two different classes altogether.

> I'm trying the latest 5.1.0 snap now, let's hope it works! ;)

> Noel

> Marcus Boerger wrote:

> > […]
