Skip to content

restore_exception_handler does not work as expected #20925

@Appla

Description

@Appla

Description

After commit 3301d96, the behavior of zend_user_exception_handler has changed. As a result, call set_exception_handler / restore_exception_handler inside exception handler no longer behaves as expected

Is this the intended behavior, or a regression?

The following code:

<?php
register_shutdown_function(function() {
    echo "DEBUG: Shutdown function 1\n";
});

register_shutdown_function(function() {
    echo "DEBUG: Shutdown function 2 will throw\n";
    throw new \RuntimeException("throw in shutdown_func");
});

set_exception_handler(function($e) {
    $rc['restore_error_handler'] = \restore_error_handler();
    $rc['restore_exception_handler'] = \restore_exception_handler();
    // $rc['restore_exception_handler_2'] = \restore_exception_handler();
    echo sprintf("DEBUG: got exception[code: %d, error: %s]", $e->getCode(), $e->getMessage()), json_encode($rc), PHP_EOL;
});

echo PHP_VERSION, PHP_EOL;
throw new RuntimeException('first exception');

Resulted in this output:

8.4.16
DEBUG: got exception[code: 0, error: first exception]{"restore_error_handler":true,"restore_exception_handler":true}
DEBUG: Shutdown function 1
DEBUG: Shutdown function 2 will throw
DEBUG: got exception[code: 0, error: throw in shutdown_func]{"restore_error_handler":true,"restore_exception_handler":true}

But I expected this output instead:

7.4.33
DEBUG: got exception[code: 0, error: first exception]{"restore_error_handler":true,"restore_exception_handler":true}
DEBUG: Shutdown function 1
DEBUG: Shutdown function 2 will throw
PHP Fatal error:  Uncaught RuntimeException: throw in shutdown_func in /path/to/test.php:9
Stack trace:
#0 [internal function]: {closure}()
#1 {main}
  thrown in /path/to/test.php on line 9

PHP Version

PHP 8.4.16 (cli) (built: Dec 16 2025 16:03:34) (NTS gcc x86_64)
Copyright (c) The PHP Group
Built by Remi's RPM repository <https://rpms.remirepo.net/> #StandWithUkraine
Zend Engine v4.4.16, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.16, Copyright (c), by Zend Technologies

PHP 7.4.33 (cli) (built: Dec 18 2025 08:02:40) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.33, Copyright (c), by Zend Technologies

Operating System

Fedora 42

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions