Skip to content

Commit

Permalink
Merge pull request #28 from clue-labs/garbage
Browse files Browse the repository at this point in the history
Clean up any garbage references when awaiting rejected promise
  • Loading branch information
WyriHaximus authored Feb 10, 2022
2 parents bc11704 + f02bfcb commit f492e65
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
19 changes: 19 additions & 0 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,25 @@ function (mixed $throwable) use (&$rejected, &$rejectedThrowable, &$fiber): void
$throwable = new \UnexpectedValueException(
'Promise rejected with unexpected value of type ' . (is_object($throwable) ? get_class($throwable) : gettype($throwable))
);

// avoid garbage references by replacing all closures in call stack.
// what a lovely piece of code!
$r = new \ReflectionProperty('Exception', 'trace');
$trace = $r->getValue($throwable);

// Exception trace arguments only available when zend.exception_ignore_args is not set
// @codeCoverageIgnoreStart
foreach ($trace as $ti => $one) {
if (isset($one['args'])) {
foreach ($one['args'] as $ai => $arg) {
if ($arg instanceof \Closure) {
$trace[$ti]['args'][$ai] = 'Object(' . \get_class($arg) . ')';
}
}
}
}
// @codeCoverageIgnoreEnd
$r->setValue($throwable, $trace);
}

if ($fiber === null) {
Expand Down
12 changes: 9 additions & 3 deletions tests/AwaitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,15 @@ public function testAwaitThrowsUnexpectedValueExceptionWhenPromiseIsRejectedWith
$reject(null);
});

$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('Promise rejected with unexpected value of type NULL');
$await($promise);
try {
$await($promise);
} catch (\UnexpectedValueException $exception) {
$this->assertInstanceOf(\UnexpectedValueException::class, $exception);
$this->assertEquals('Promise rejected with unexpected value of type NULL', $exception->getMessage());
$this->assertEquals(0, $exception->getCode());
$this->assertNull($exception->getPrevious());
$this->assertNotEquals('', $exception->getTraceAsString());
}
}

/**
Expand Down

0 comments on commit f492e65

Please sign in to comment.