Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using await and returning response as promise does not work #263

Open
map-g opened this issue Nov 1, 2024 · 1 comment
Open

Using await and returning response as promise does not work #263

map-g opened this issue Nov 1, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@map-g
Copy link

map-g commented Nov 1, 2024

When using React\Async\await somewhere and then returning the response as a promise (e.g. a promise got from React\Http\Browser::get(), in the example it's replaced by a simple resolve($response)), an assertion in the \FrameworkX\Io\FiberHandler (line 49: assert($response instanceof ResponseInterface);) will fail. After removing this assertion it seems to work fine.
Returning the promise without any React\Async\await before does not reveal this.

#!/usr/bin/env php
<?php

declare(strict_types=1);

use function React\Async\await;
use function React\Promise\resolve;
use function React\Promise\Timer\sleep;

require __DIR__ . '/../vendor/autoload.php';

$app = new FrameworkX\App();

$app->get('/', function () {
    await(sleep(3));
    $response = React\Http\Message\Response::plaintext(
        "Hello world!\n",
    );
    return resolve($response);
});

$app->run();
@map-g map-g added the bug Something isn't working label Nov 1, 2024
@panariga
Copy link

panariga commented Nov 27, 2024

The issue occurs because you're combining React\Async\await with a Promise returned later in the function. The await() function unwraps the promise but doesn't preserve its "react promise context". This causes the assertion in FrameworkX\Io\FiberHandler to fail because the returned value doesn't conform to expectations.

To fix this, you don't need to use await() in this specific handler. Instead, you should directly chain the sleep() promise and return your response inside the then() callback:

$app->get('/', function () {
    // Use sleep() and properly wrap the response inside the promise chain
    return sleep(3)->then(function () {
        return new React\Http\Message\Response(
            200,
            ['Content-Type' => 'text/plain'],
            "Hello world!\n"
        );
    });
});

This way, you avoid any interference between React\Async\await and promise-handling mechanisms.

The key takeaway is: use sleep() directly when asynchronous behavior is required, and avoid mixing await() with returned promises unless you're certain the environment supports such usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants
@panariga @map-g and others