@@ -18,9 +18,9 @@ class JobExceptionHandlingTest : TestBase() {
18
18
/*
19
19
* Root parent: JobImpl()
20
20
* Child: throws ISE
21
- * Result: ISE in exception handler
21
+ * Result: ISE in exception handlerWithContextExceptionHandlingTest
22
22
*/
23
- val exception = runBlock {
23
+ val exception = captureExceptionsRun {
24
24
val job = Job ()
25
25
launch(job, start = ATOMIC ) {
26
26
expect(2 )
@@ -36,43 +36,39 @@ class JobExceptionHandlingTest : TestBase() {
36
36
}
37
37
38
38
@Test
39
- fun testAsyncCancellationWithCause () = runTest {
40
- val deferred = async(NonCancellable ) {
39
+ fun testAsyncCancellationWithCauseAndParent () = runTest {
40
+ val parent = Job ()
41
+ val deferred = async(parent) {
41
42
expect(2 )
42
43
delay(Long .MAX_VALUE )
43
44
}
44
45
45
46
expect(1 )
46
47
yield ()
47
- deferred.cancel( TestCancellationException ( " TEST " ))
48
+ parent.completeExceptionally( IOException ( ))
48
49
try {
49
50
deferred.await()
50
51
expectUnreached()
51
- } catch (e: TestCancellationException ) {
52
- assertEquals(" TEST" , e.message)
52
+ } catch (e: CancellationException ) {
53
53
assertTrue(e.suppressed.isEmpty())
54
+ assertTrue(e.cause?.suppressed?.isEmpty() ? : false )
54
55
finish(3 )
55
56
}
56
57
}
57
58
58
59
@Test
59
- fun testAsyncCancellationWithCauseAndParent () = runTest {
60
+ fun testAsyncCancellationWithCauseAndParentDoesNotTriggerHandling () = runTest {
60
61
val parent = Job ()
61
- val deferred = async (parent) {
62
+ val job = launch (parent) {
62
63
expect(2 )
63
64
delay(Long .MAX_VALUE )
64
65
}
65
66
66
67
expect(1 )
67
68
yield ()
68
69
parent.completeExceptionally(IOException ())
69
- try {
70
- deferred.await()
71
- expectUnreached()
72
- } catch (e: IOException ) {
73
- assertTrue(e.suppressed.isEmpty())
74
- finish(3 )
75
- }
70
+ job.join()
71
+ finish(3 )
76
72
}
77
73
78
74
@Test
@@ -85,7 +81,7 @@ class JobExceptionHandlingTest : TestBase() {
85
81
*
86
82
* Github issue #354
87
83
*/
88
- val exception = runBlock {
84
+ val exception = captureExceptionsRun {
89
85
val job = Job ()
90
86
val child = launch(job, start = ATOMIC ) {
91
87
expect(2 )
@@ -109,7 +105,7 @@ class JobExceptionHandlingTest : TestBase() {
109
105
* Inner child: throws AE
110
106
* Result: AE in exception handler
111
107
*/
112
- val exception = runBlock {
108
+ val exception = captureExceptionsRun {
113
109
val job = Job ()
114
110
launch(job) {
115
111
expect(2 ) // <- child is launched successfully
@@ -145,7 +141,7 @@ class JobExceptionHandlingTest : TestBase() {
145
141
* Inner child: throws AE
146
142
* Result: AE
147
143
*/
148
- val exception = runBlock {
144
+ val exception = captureExceptionsRun {
149
145
val job = Job ()
150
146
launch(job, start = ATOMIC ) {
151
147
expect(2 )
@@ -173,7 +169,7 @@ class JobExceptionHandlingTest : TestBase() {
173
169
* Inner child: throws AE
174
170
* Result: IOE with suppressed AE
175
171
*/
176
- val exception = runBlock {
172
+ val exception = captureExceptionsRun {
177
173
val job = Job ()
178
174
launch(job) {
179
175
expect(2 ) // <- child is launched successfully
@@ -196,11 +192,9 @@ class JobExceptionHandlingTest : TestBase() {
196
192
finish(5 )
197
193
}
198
194
199
- assertTrue(exception is IOException )
195
+ assertTrue(exception is ArithmeticException )
200
196
assertNull(exception.cause)
201
- val suppressed = exception.suppressed
202
- assertEquals(1 , suppressed.size)
203
- checkException<ArithmeticException >(suppressed[0 ])
197
+ assertTrue(exception.suppressed.isEmpty())
204
198
}
205
199
206
200
@Test
@@ -211,7 +205,7 @@ class JobExceptionHandlingTest : TestBase() {
211
205
* Child: launch 3 children, each of them throws an exception (AE, IOE, IAE) and calls delay()
212
206
* Result: AE with suppressed IOE and IAE
213
207
*/
214
- val exception = runBlock {
208
+ val exception = captureExceptionsRun {
215
209
val job = Job ()
216
210
launch(job, start = ATOMIC ) {
217
211
expect(2 )
@@ -253,7 +247,7 @@ class JobExceptionHandlingTest : TestBase() {
253
247
* Child: launch 2 children (each of them throws an exception (IOE, IAE)), throws AE
254
248
* Result: AE with suppressed IOE and IAE
255
249
*/
256
- val exception = runBlock {
250
+ val exception = captureExceptionsRun {
257
251
val job = Job ()
258
252
launch(job, start = ATOMIC ) {
259
253
expect(2 )
@@ -282,6 +276,34 @@ class JobExceptionHandlingTest : TestBase() {
282
276
assertTrue(suppressed[1 ] is IllegalArgumentException )
283
277
}
284
278
279
+ @Test
280
+ fun testExceptionIsHandledOnce () = runTest(unhandled = listOf { e -> e is TestException }) {
281
+ val job = Job ()
282
+ val j1 = launch(job) {
283
+ expect(1 )
284
+ delay(Long .MAX_VALUE )
285
+ }
286
+
287
+ val j2 = launch(job) {
288
+ expect(2 )
289
+ throw TestException ()
290
+ }
291
+
292
+ joinAll(j1 ,j2)
293
+ finish(3 )
294
+ }
295
+
296
+ @Test
297
+ fun testCancelledParent () = runTest {
298
+ expect(1 )
299
+ val parent = Job ()
300
+ parent.completeExceptionally(TestException ())
301
+ launch(parent) {
302
+ expectUnreached()
303
+ }.join()
304
+ finish(2 )
305
+ }
306
+
285
307
@Test
286
308
fun testBadException () = runTest(unhandled = listOf ({e -> e is BadException })) {
287
309
val job = launch(Job ()) {
0 commit comments