frankenphp icon indicating copy to clipboard operation
frankenphp copied to clipboard

Are set_error_handler and set_exception_handler working?

Open giorgiopogliani opened this issue 9 months ago • 3 comments

I am using the worker mode and it doesn't seem that the handlers are called.

giorgiopogliani avatar Mar 06 '25 15:03 giorgiopogliani

Can you give some example code on how you are trying to register handlers and what you are seeing instead?

AlliBalliBaba avatar Mar 07 '25 16:03 AlliBalliBaba

I am using a Craft CMS which is based on Yii2 framework and I wrote the worker mode like this (simplified for the sake of brevity):

<?php

ignore_user_abort(true);

// Load shared bootstrap
require dirname(__DIR__) . '/bootstrap.php';

// Load and run Craft
/** @var craft\web\Application $app */
$app = require CRAFT_VENDOR_PATH . '/craftcms/cms/bootstrap/web.php';

// Handler outside the loop for better performance (doing less work)
$handler = static function () use ($app) {
    // Tried with this or without but the response status sent is 500, instead of the usual debug view
    $app->get('errorHandler')->unregister();
    $app->get('errorHandler')->register();

    // My solution was to wrap this in a try catch and call the handler myself
    $app->run();
};

$maxRequests = (int)($_SERVER['MAX_REQUESTS'] ?? 0);
for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests) {
    $keepRunning = \frankenphp_handle_request($handler);

    // Call the garbage collector to reduce the chances of it being triggered in the middle of a page generation
    gc_collect_cycles();

    if (!$keepRunning) {
        break;
    }
}

You can look a the error handler here: https://github.com/yiisoft/yii2/blob/master/framework/base/ErrorHandler.php#L86-L122

I found a fix but wanted to understand if these functions should work and maybe I am doing something wrong.

giorgiopogliani avatar Mar 07 '25 17:03 giorgiopogliani

Yeah I think the issue is that the global exception handler never gets reached in this case, since the exception gets automatically caught by frankenphp_handle_request. In order to reach the global exception handler, the whole worker script would need to be stopped.

Wrapping the handler within a try catch block (as you did) is the recommended approach for workers and also allows better control over the request flow in general.

AlliBalliBaba avatar Mar 07 '25 18:03 AlliBalliBaba

set_error_handler works fine for me. set_exception_handler instead doesn't: I opened a PR to update the baseline example in the docs so it's easier for newcomers to soon adapt the try-catch approach

Slamdunk avatar Sep 26 '25 12:09 Slamdunk