Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function await($promise = null, $unwrap = false)
});
Utils::queue()->run();

if ($exception instanceof \Exception) {
if ($exception instanceof \Throwable) {
if (!$unwrap) {
return $exception;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/promise-adapter/src/Adapter/ReactPromiseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function await($promise = null, $unwrap = false)
$wait = false;
});

if ($exception instanceof \Exception) {
if ($exception instanceof \Throwable) {
if (!$unwrap) {
return $exception;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ public function await($promise = null, $unwrap = false)

try {
$resolvedValue = $promiseAdapter->wait($promise);
} catch (\Exception $reason) {
} catch (\Throwable $reason) {
$exception = $reason;
}
if ($exception instanceof \Exception) {
if ($exception instanceof \Throwable) {
if (!$unwrap) {
return $exception;
}
Expand Down Expand Up @@ -159,7 +159,7 @@ public function cancel($promise)
}
try {
$canceller([$adoptedPromise, 'resolve'], [$adoptedPromise, 'reject']);
} catch (\Exception $reason) {
} catch (\Throwable $reason) {
$adoptedPromise->reject($reason);
}
}
Expand Down
24 changes: 24 additions & 0 deletions lib/promise-adapter/tests/AdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,30 @@ public function testAwaitWithUnwrap(PromiseAdapterInterface $Adapter)
$Adapter->await($promise, true);
}

/**
* @param PromiseAdapterInterface $Adapter
*/
#[DataProvider('AdapterDataProvider')]
public function testAwaitReturnsErrorRejectionWithoutUnwrap(PromiseAdapterInterface $Adapter)
{
$expected = new \Error('error!');
$promise = $Adapter->createRejected($expected);

$this->assertSame($expected, $Adapter->await($promise, false));
}

/**
* @param PromiseAdapterInterface $Adapter
*/
#[DataProvider('AdapterDataProvider')]
public function testAwaitThrowsErrorRejectionWithUnwrap(PromiseAdapterInterface $Adapter)
{
$this->expectException(\Error::class);
$this->expectExceptionMessage('error!');

$Adapter->await($Adapter->createRejected(new \Error('error!')), true);
}

/**
* @param PromiseAdapterInterface $Adapter
*/
Expand Down
14 changes: 7 additions & 7 deletions src/DataLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ public function prime($key, $value)

// Only add the key if it does not already exist.
if (!$this->promiseCache->has($cacheKey)) {
// Cache a rejected promise if the value is an Error, in order to match
// Cache a rejected promise if the value is a Throwable, in order to match
// the behavior of load(key).
$promise = $value instanceof \Exception ? $this->getPromiseAdapter()->createRejected($value) : $this->getPromiseAdapter()->createFulfilled($value);
$promise = $value instanceof \Throwable ? $this->getPromiseAdapter()->createRejected($value) : $this->getPromiseAdapter()->createFulfilled($value);

$this->promiseCache->set($cacheKey, $promise);
}
Expand All @@ -173,7 +173,7 @@ public function __destruct()
foreach ($this->queue as $data) {
try {
$this->getPromiseAdapter()->cancel($data['promise']);
} catch (\Exception $e) {
} catch (\Throwable $e) {
// no need to do nothing if cancel failed
}
}
Expand Down Expand Up @@ -235,7 +235,7 @@ function ($reason) use (&$isPromiseCompleted, &$rejectedReason) {
//Promise is completed?
if ($isPromiseCompleted) {
// rejected ?
if ($rejectedReason instanceof \Exception || (interface_exists('\Throwable') && $rejectedReason instanceof \Throwable)) {
if ($rejectedReason instanceof \Throwable) {
if (!$unwrap) {
return $rejectedReason;
}
Expand Down Expand Up @@ -364,7 +364,7 @@ function ($values) use ($keys, $queue) {
// loaded queue.
foreach ($queue as $index => $data) {
$value = $values[$index];
if ($value instanceof \Exception) {
if ($value instanceof \Throwable) {
$data['reject']($value);
} else {
$data['resolve']($value);
Expand All @@ -380,9 +380,9 @@ function ($values) use ($keys, $queue) {
* Do not cache individual loads if the entire batch dispatch fails,
* but still reject each request so they do not hang.
* @param array $queue
* @param \Exception $error
* @param \Throwable $error
*/
private function failedDispatch($queue, \Exception $error)
private function failedDispatch($queue, \Throwable $error)
{
foreach ($queue as $index => $data) {
$this->clear($data['key']);
Expand Down
2 changes: 1 addition & 1 deletion src/DataLoaderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function prime($key, $value);
* @param $promise
* @param bool $unwrap controls whether or not the value of the promise is returned for a fulfilled promise or if an exception is thrown if the promise is rejected
* @return mixed
* @throws \Exception
* @throws \Throwable
*/
public static function await($promise = null, $unwrap = true);
}
59 changes: 59 additions & 0 deletions tests/DataLoadTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,47 @@ public function testHandlesPrimingTheCacheWithAnError()
$this->assertEquals([], $loadCalls->getArrayCopy());
}

/**
* @group represents-errors
*/
public function testRejectsErrorUsedToPrimeTheCache()
{
list($identityLoader, $loadCalls) = self::idLoader();
$expected = new \Error('Error: 1');

$identityLoader->prime(1, $expected);

$caught = null;
try {
DataLoader::await($identityLoader->load(1));
} catch (\Error $error) {
$caught = $error;
}

$this->assertSame($expected, $caught);
$this->assertEquals([], $loadCalls->getArrayCopy());
}

/**
* @group represents-errors
*/
public function testRejectsErrorReturnedAsAnIndividualBatchValue()
{
$expected = new \Error('Error: 1');
list($loader) = self::idLoader(null, function () use ($expected) {
return self::$promiseAdapter->createFulfilled([$expected]);
});

$caught = null;
try {
DataLoader::await($loader->load(1));
} catch (\Error $error) {
$caught = $error;
}

$this->assertSame($expected, $caught);
}

/**
* @group represents-errors
*/
Expand Down Expand Up @@ -451,6 +492,24 @@ public function testPropagatesErrorToAllLoads()
$this->assertEquals([[1, 2]], $loadCalls->getArrayCopy());
}

/**
* @group represents-errors
*/
public function testPropagatesErrorFromFailedBatchToAllLoads()
{
$expected = new \Error('I am a terrible loader');
list($failLoader, $loadCalls) = self::idLoader(null, function () use ($expected) {
return self::$promiseAdapter->createRejected($expected);
});

$promise1 = $failLoader->load(1);
$promise2 = $failLoader->load(2);

$this->assertSame($expected, DataLoader::await($promise1, false));
$this->assertSame($expected, DataLoader::await($promise2, false));
$this->assertEquals([[1, 2]], $loadCalls->getArrayCopy());
}

/**
* @group accepts-any-kind-of-key
*/
Expand Down
Loading