Search code examples
phpasynchronousexceptionpromisereactphp

Syntax error in a promise before the promise is returned


Here's a simple event loop with a ReactPHP promise:

new React\Http\Server([
    function(ServerRequestInterface $request) {
        $deferred = new React\Promise\Deferred();
        $promise = $deferred->promise();

        $deferred->reject(new Response(500));

        return $promise;
    }
]);

In this case everything works fine and the server returns 500, because the promise was returned and it was rejected.

But how to handle cases like this:

new React\Http\Server([
    function(ServerRequestInterface $request) {
        $deferred = new React\Promise\Deferred();
        $promise = $deferred->promise();

        SynTaxErrO..2!((r();

        $deferred->reject(new Response(500));

        return $promise;
    }
]);

The server/loop will still be running, but the connection will be hanging, since a syntax error happened before the promise was returned.

My first assumption was to use try-catch, but it doesn't seem to work in PHP.

try {
    SynTaxErrO..2!((r();
} catch($e) {
    $deferred->reject(new Response(500));
    return $promise;
}

Is there a way to deal with cases like this and still return 500 instead of just hanging and waiting for a promise that was never returned? In real code I have a router function that returns a promise. The promise is never retuned if one of the routes have a syntax error, and thus the connection just hangs. There are no error messages as well.


Solution

  • You cannot catch syntax errors. If there is a syntax error before your catch statement, then execution never reaches your catch and therefore is like it didn't exist. To detect syntax error use a linter (for instance, php -l) before executing your code.

    For other kinds of errors, provided you are using PHP 7, then you can use

    catch (Error $e) { ... }
    

    or a set_exception_handler() handler to catch errors.

    If you want to catch both errors and exceptions, then you can use a block like

    catch (Throwable $e) { ... }
    

    If you only want to catch exceptions, use

    catch (Exception $e) { ... }
    

    See http://php.net/manual/en/language.errors.php7.php for more info