5151function await (PromiseInterface $ promise )
5252{
5353 $ wait = true ;
54- $ resolved = null ;
55- $ exception = null ;
54+ $ resolved = false ;
5655 $ rejected = false ;
56+ $ resolvedValue = null ;
57+ $ rejectedThrowable = null ;
5758
5859 $ promise ->then (
59- function ($ c ) use (&$ resolved , &$ wait ) {
60- $ resolved = $ c ;
60+ function ($ c ) use (&$ resolved , &$ resolvedValue , &$ wait ) {
61+ $ resolvedValue = $ c ;
62+ $ resolved = true ;
6163 $ wait = false ;
6264 Loop::stop ();
6365 },
64- function ($ error ) use (&$ exception , &$ rejected , &$ wait ) {
65- $ exception = $ error ;
66+ function ($ error ) use (&$ rejected , &$ rejectedThrowable , &$ wait ) {
67+ // promise is rejected with an unexpected value (Promise API v1 or v2 only)
68+ if (!$ error instanceof \Exception && !$ error instanceof \Throwable) {
69+ $ error = new \UnexpectedValueException (
70+ 'Promise rejected with unexpected value of type ' . (is_object ($ error ) ? get_class ($ error ) : gettype ($ error ))
71+ );
72+
73+ // avoid garbage references by replacing all closures in call stack.
74+ // what a lovely piece of code!
75+ $ r = new \ReflectionProperty ('Exception ' , 'trace ' );
76+ $ trace = $ r ->getValue ($ error );
77+
78+ // Exception trace arguments only available when zend.exception_ignore_args is not set
79+ // @codeCoverageIgnoreStart
80+ foreach ($ trace as $ ti => $ one ) {
81+ if (isset ($ one ['args ' ])) {
82+ foreach ($ one ['args ' ] as $ ai => $ arg ) {
83+ if ($ arg instanceof \Closure) {
84+ $ trace [$ ti ]['args ' ][$ ai ] = 'Object( ' . \get_class ($ arg ) . ') ' ;
85+ }
86+ }
87+ }
88+ }
89+ // @codeCoverageIgnoreEnd
90+ $ r ->setValue ($ error , $ trace );
91+ }
92+
93+ $ rejectedThrowable = $ error ;
6694 $ rejected = true ;
6795 $ wait = false ;
6896 Loop::stop ();
@@ -73,22 +101,23 @@ function ($error) use (&$exception, &$rejected, &$wait) {
73101 // argument does not show up in the stack trace in PHP 7+ only.
74102 $ promise = null ;
75103
104+ if ($ rejected ) {
105+ throw $ rejectedThrowable ;
106+ }
107+
108+ if ($ resolved ) {
109+ return $ resolvedValue ;
110+ }
111+
76112 while ($ wait ) {
77113 Loop::run ();
78114 }
79115
80116 if ($ rejected ) {
81- // promise is rejected with an unexpected value (Promise API v1 or v2 only)
82- if (!$ exception instanceof \Exception && !$ exception instanceof \Throwable) {
83- $ exception = new \UnexpectedValueException (
84- 'Promise rejected with unexpected value of type ' . (is_object ($ exception ) ? get_class ($ exception ) : gettype ($ exception ))
85- );
86- }
87-
88- throw $ exception ;
117+ throw $ rejectedThrowable ;
89118 }
90119
91- return $ resolved ;
120+ return $ resolvedValue ;
92121}
93122
94123/**
0 commit comments