1+ --TEST--
2+ GC 004: Exception handling with suspend in destructor
3+ --FILE--
4+ <?php
5+
6+ use function Async \spawn ;
7+ use function Async \suspend ;
8+
9+ class TestObject {
10+ public $ value ;
11+ public $ should_throw ;
12+
13+ public function __construct ($ value , $ should_throw = false ) {
14+ $ this ->value = $ value ;
15+ $ this ->should_throw = $ should_throw ;
16+ echo "Created: {$ this ->value }\n" ;
17+ }
18+
19+ public function __destruct () {
20+ echo "Destructor start: {$ this ->value }\n" ;
21+
22+ try {
23+ // Suspend in destructor
24+ echo "Suspended in destructor: {$ this ->value }\n" ;
25+ suspend ();
26+
27+ if ($ this ->should_throw ) {
28+ throw new Exception ("Test exception after suspend " );
29+ }
30+
31+ echo "Destructor middle: {$ this ->value }\n" ;
32+
33+ } catch (Exception $ e ) {
34+ echo "Exception caught in destructor: {$ e ->getMessage ()}\n" ;
35+ }
36+
37+ echo "Destructor end: {$ this ->value }\n" ;
38+ }
39+ }
40+
41+ spawn (function () {
42+ echo "Starting test \n" ;
43+
44+ // Test 1: Normal case without exception
45+ echo "=== Test 1: Normal case === \n" ;
46+ $ obj1 = new TestObject ("normal " , false );
47+ unset($ obj1 );
48+ gc_collect_cycles ();
49+
50+ suspend ();
51+
52+ // Test 2: Exception case
53+ echo "=== Test 2: Exception case === \n" ;
54+ $ obj2 = new TestObject ("exception " , true );
55+ unset($ obj2 );
56+ gc_collect_cycles ();
57+
58+ suspend ();
59+
60+ echo "Test complete \n" ;
61+ });
62+
63+ ?>
64+ --EXPECT--
65+ Starting test
66+ === Test 1: Normal case ===
67+ Created: normal
68+ Destructor start: normal
69+ Suspended in destructor: normal
70+ Destructor middle: normal
71+ Destructor end: normal
72+ === Test 2: Exception case ===
73+ Created: exception
74+ Destructor start: exception
75+ Suspended in destructor: exception
76+ Exception caught in destructor: Test exception after suspend
77+ Destructor end: exception
78+ Test complete
0 commit comments