Skip to content

Commit c546bf6

Browse files
committed
Throw UnexpectedValueException if rejected with non-Exception
1 parent 44a5c3e commit c546bf6

4 files changed

Lines changed: 63 additions & 2 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ $result = Block\await($promise, $loop);
118118
Once the promise is resolved, this will return whatever the promise resolves to.
119119

120120
Once the promise is rejected, this will throw whatever the promise rejected with.
121+
If the promise did not reject with an `Exception`, then this function will
122+
throw an `UnexpectedValueException` instead.
121123

122124
```php
123125
try {
@@ -185,6 +187,8 @@ be used to correlate the return array to the promises passed.
185187

186188
If ANY promise fails to resolve, this will try to `cancel()` all
187189
remaining promises and throw an `Exception`.
190+
If the promise did not reject with an `Exception`, then this function will
191+
throw an `UnexpectedValueException` instead.
188192

189193
If no $timeout is given and either promise stays pending, then this will
190194
potentially wait/block forever until the last promise is settled.

src/functions.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ function sleep($time, LoopInterface $loop)
2828
* Once the promise is resolved, this will return whatever the promise resolves to.
2929
*
3030
* Once the promise is rejected, this will throw whatever the promise rejected with.
31+
* If the promise did not reject with an `Exception`, then this function will
32+
* throw an `UnexpectedValueException` instead.
3133
*
3234
* If no $timeout is given and the promise stays pending, then this will
3335
* potentially wait/block forever until the promise is settled.
@@ -47,6 +49,7 @@ function await(PromiseInterface $promise, LoopInterface $loop, $timeout = null)
4749
$wait = true;
4850
$resolved = null;
4951
$exception = null;
52+
$rejected = false;
5053

5154
if ($timeout !== null) {
5255
$promise = Timer\timeout($promise, $timeout, $loop);
@@ -58,8 +61,9 @@ function ($c) use (&$resolved, &$wait, $loop) {
5861
$wait = false;
5962
$loop->stop();
6063
},
61-
function ($error) use (&$exception, &$wait, $loop) {
64+
function ($error) use (&$exception, &$rejected, &$wait, $loop) {
6265
$exception = $error;
66+
$rejected = true;
6367
$wait = false;
6468
$loop->stop();
6569
}
@@ -69,7 +73,15 @@ function ($error) use (&$exception, &$wait, $loop) {
6973
$loop->run();
7074
}
7175

72-
if ($exception !== null) {
76+
if ($rejected) {
77+
if (!$exception instanceof \Exception) {
78+
$exception = new \UnexpectedValueException(
79+
'Promise rejected with unexpected value of type ' . (is_object(($exception) ? get_class($exception) : gettype($exception))),
80+
0,
81+
$exception instanceof \Throwable ? $exception : null
82+
);
83+
}
84+
7385
throw $exception;
7486
}
7587

@@ -139,6 +151,8 @@ function awaitAny(array $promises, LoopInterface $loop, $timeout = null)
139151
*
140152
* If ANY promise fails to resolve, this will try to cancel() all
141153
* remaining promises and throw an Exception.
154+
* If the promise did not reject with an `Exception`, then this function will
155+
* throw an `UnexpectedValueException` instead.
142156
*
143157
* If no $timeout is given and either promise stays pending, then this will
144158
* potentially wait/block forever until the last promise is settled.

tests/FunctionAwaitAllTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ public function testAwaitAllRejected()
3232
Block\awaitAll($all, $this->loop);
3333
}
3434

35+
public function testAwaitAllRejectedWithFalseWillWrapInUnexpectedValueException()
36+
{
37+
$all = array(
38+
$this->createPromiseResolved(1),
39+
Promise\reject(false)
40+
);
41+
42+
$this->setExpectedException('UnexpectedValueException');
43+
Block\awaitAll($all, $this->loop);
44+
}
45+
3546
public function testAwaitAllOnlyRejected()
3647
{
3748
$all = array(

tests/FunctionAwaitTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,38 @@ public function testAwaitOneRejected()
1414
Block\await($promise, $this->loop);
1515
}
1616

17+
public function testAwaitOneRejectedWithFalseWillWrapInUnexpectedValueException()
18+
{
19+
$promise = Promise\reject(false);
20+
21+
$this->setExpectedException('UnexpectedValueException');
22+
Block\await($promise, $this->loop);
23+
}
24+
25+
public function testAwaitOneRejectedWithNullWillWrapInUnexpectedValueException()
26+
{
27+
$promise = Promise\reject(null);
28+
29+
$this->setExpectedException('UnexpectedValueException');
30+
Block\await($promise, $this->loop);
31+
}
32+
33+
/**
34+
* @requires PHP 7
35+
*/
36+
public function testAwaitOneRejectedWithPhp7ErrorWillWrapInUnexpectedValueExceptionWithPrevious()
37+
{
38+
$promise = Promise\reject(new Error('Test'));
39+
40+
try {
41+
Block\await($promise, $this->loop);
42+
$this->fail();
43+
} catch (UnexpectedValueException $e) {
44+
$this->assertInstanceOf('Throwable', $e->getPrevious());
45+
$this->assertEquals('Test', $e->getPrevious()->getMessage());
46+
}
47+
}
48+
1749
public function testAwaitOneResolved()
1850
{
1951
$promise = $this->createPromiseResolved(2);

0 commit comments

Comments
 (0)