Skip to content

Commit e4be2e6

Browse files
authored
Merge pull request #27 from clue-labs/exception
Throw UnexpectedValueException if Promise gets rejected with non-Exception
2 parents 74dc686 + c546bf6 commit e4be2e6

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

README.md

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

125125
Once the promise is rejected, this will throw whatever the promise rejected with.
126+
If the promise did not reject with an `Exception`, then this function will
127+
throw an `UnexpectedValueException` instead.
126128

127129
```php
128130
try {
@@ -194,6 +196,8 @@ be used to correlate the return array to the promises passed.
194196

195197
If ANY promise fails to resolve, this will try to `cancel()` all
196198
remaining promises and throw an `Exception`.
199+
If the promise did not reject with an `Exception`, then this function will
200+
throw an `UnexpectedValueException` instead.
197201

198202
If no $timeout is given and either promise stays pending, then this will
199203
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
@@ -33,6 +33,8 @@ function sleep($time, LoopInterface $loop)
3333
* Once the promise is resolved, this will return whatever the promise resolves to.
3434
*
3535
* Once the promise is rejected, this will throw whatever the promise rejected with.
36+
* If the promise did not reject with an `Exception`, then this function will
37+
* throw an `UnexpectedValueException` instead.
3638
*
3739
* If no $timeout is given and the promise stays pending, then this will
3840
* potentially wait/block forever until the promise is settled.
@@ -54,6 +56,7 @@ function await(PromiseInterface $promise, LoopInterface $loop, $timeout = null)
5456
$wait = true;
5557
$resolved = null;
5658
$exception = null;
59+
$rejected = false;
5760

5861
if ($timeout !== null) {
5962
$promise = Timer\timeout($promise, $timeout, $loop);
@@ -65,8 +68,9 @@ function ($c) use (&$resolved, &$wait, $loop) {
6568
$wait = false;
6669
$loop->stop();
6770
},
68-
function ($error) use (&$exception, &$wait, $loop) {
71+
function ($error) use (&$exception, &$rejected, &$wait, $loop) {
6972
$exception = $error;
73+
$rejected = true;
7074
$wait = false;
7175
$loop->stop();
7276
}
@@ -76,7 +80,15 @@ function ($error) use (&$exception, &$wait, $loop) {
7680
$loop->run();
7781
}
7882

79-
if ($exception !== null) {
83+
if ($rejected) {
84+
if (!$exception instanceof \Exception) {
85+
$exception = new \UnexpectedValueException(
86+
'Promise rejected with unexpected value of type ' . (is_object(($exception) ? get_class($exception) : gettype($exception))),
87+
0,
88+
$exception instanceof \Throwable ? $exception : null
89+
);
90+
}
91+
8092
throw $exception;
8193
}
8294

@@ -148,6 +160,8 @@ function awaitAny(array $promises, LoopInterface $loop, $timeout = null)
148160
*
149161
* If ANY promise fails to resolve, this will try to cancel() all
150162
* remaining promises and throw an Exception.
163+
* If the promise did not reject with an `Exception`, then this function will
164+
* throw an `UnexpectedValueException` instead.
151165
*
152166
* If no $timeout is given and either promise stays pending, then this will
153167
* 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)