promise: Difficulty testing with exception design

Contrary to #46 perhaps we shouldn’t be catching \Exception in function then() at all.

Just spent a bit of time debugging why I couldn’t unit test promises.

$promise->then(function($results) {
    $this->assertCount(2, $results);
});

This was not failing the test when count was not correct. Finally figured out that phpunit is actually throwing an exception when the assert fails (I didn’t know this), and promise->then() uses a try/catch around the resolve call (I also didn’t know this.)

I feel like the try/catch from within the then() function probably makes things more difficult than it helps.

Granted, my workaround is to use(&$rowcount), but it still seems throwing an exception from within a resolve, ought to bounce out to the caller.

$rowcount = false;
$promise->then(function($results) use (&$rowcount) {
    $rowcount = count($results);
});
$this->assertEquals(2, $rowcount);

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 17 (4 by maintainers)

Most upvoted comments

@dustingraham You are thinking in a sync way. Seem’s like you are not considering the real purpose of promises.

Look at this sync code:

try {
     $result = someSyncOperation(); // will block and return when it's complete
} catch (\Exception $exception) {
    echo "Error while doing Operation!";
    $result = false;
}

// $result here sure will be the return value of someSyncOperation() or false on error.
// Just because it's sync!

Now consider an async version like this:

$result = null;

someAsyncOperation() // if it's a true async function, will return immediately.
    ->then(function ($value) use (&$result) {
        $result = $value;

        // $result here sure will be the return value of someAsyncOperation().
        // But at this point could be a future time.
    })
    ->catch(function (\Exception $exception) {
        // Here the operation or what happened inside then() failed for sure.
    });

// $result here probabily still will be null!
// Because everything above just returned immediately.

When you try to write a test in a sync way with PHPUnit real results will be wasted and exceptions will be thrown to the limbo, just because your test method will return before.

Your workaround in second code would only in a few cases, the ones where $promise holds a false async operation (a promise that resolves or rejects synchronously).

Closing for now, but I may ping you depending on how implementation goes. Working on it now. Still wrapping my mind around the flow between the two layers of promises.

Thanks.