Skip to content

Commit 590696d

Browse files
qwwdfsadelizarov
authored andcommitted
Exception handling coroutines guide
1 parent 91ecee8 commit 590696d

File tree

10 files changed

+556
-10
lines changed

10 files changed

+556
-10
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
6+
package kotlinx.coroutines.experimental.guide.exceptions01
7+
8+
import kotlinx.coroutines.experimental.*
9+
10+
fun main(args: Array<String>) = runBlocking {
11+
val job = launch {
12+
println("Throwing exception from launch")
13+
throw IndexOutOfBoundsException() // Will be printed to the console by Thread.defaultUncaughtExceptionHandler
14+
}
15+
16+
job.join()
17+
println("Joined failed job")
18+
19+
val deferred = async {
20+
println("Throwing exception from async")
21+
throw ArithmeticException() // Nothing is printed, relying on user to call await
22+
}
23+
24+
try {
25+
deferred.await()
26+
println("Unreached")
27+
} catch (e: ArithmeticException) {
28+
println("Caught ArithmeticException")
29+
}
30+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
6+
package kotlinx.coroutines.experimental.guide.exceptions02
7+
8+
import kotlinx.coroutines.experimental.*
9+
10+
fun main(args: Array<String>) = runBlocking {
11+
val handler = CoroutineExceptionHandler { _, exception -> println("Caught $exception") }
12+
13+
val job = launch(handler) {
14+
throw AssertionError()
15+
}
16+
17+
val deferred = async(handler) {
18+
throw ArithmeticException() // Nothing will be printed, relying on user to call deferred.await()
19+
}
20+
21+
joinAll(job, deferred)
22+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
6+
package kotlinx.coroutines.experimental.guide.exceptions03
7+
8+
import kotlinx.coroutines.experimental.*
9+
import kotlin.coroutines.experimental.*
10+
11+
fun main(args: Array<String>) = runBlocking {
12+
val job = launch(coroutineContext, parent = Job()) {
13+
val child = launch(coroutineContext) {
14+
try {
15+
delay(Long.MAX_VALUE)
16+
} finally {
17+
println("Child is cancelled")
18+
}
19+
}
20+
21+
yield()
22+
println("Cancelling child")
23+
child.cancel()
24+
child.join()
25+
yield()
26+
println("Parent is not cancelled")
27+
}
28+
29+
job.join()
30+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
6+
package kotlinx.coroutines.experimental.guide.exceptions04
7+
8+
import kotlinx.coroutines.experimental.*
9+
import kotlin.coroutines.experimental.*
10+
11+
fun main(args: Array<String>) = runBlocking {
12+
val handler = CoroutineExceptionHandler { _, exception -> println("Caught $exception") }
13+
14+
val job = launch(handler) {
15+
val child1 = launch(coroutineContext, start = CoroutineStart.ATOMIC) {
16+
try {
17+
delay(Long.MAX_VALUE)
18+
} finally {
19+
withContext(NonCancellable) {
20+
println("Children are cancelled, but exception is not handled until children are terminated completely")
21+
delay(100)
22+
println("Last child finished its non cancellable block")
23+
}
24+
}
25+
}
26+
27+
val child2 = launch(coroutineContext, start = CoroutineStart.ATOMIC) {
28+
delay(10)
29+
println("Child throws an exception")
30+
throw ArithmeticException()
31+
}
32+
}
33+
34+
job.join()
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
6+
package kotlinx.coroutines.experimental.guide.exceptions05
7+
8+
import kotlinx.coroutines.experimental.*
9+
import kotlinx.coroutines.experimental.exceptions.*
10+
import java.io.*
11+
import kotlin.coroutines.experimental.*
12+
13+
fun main(args: Array<String>) = runBlocking {
14+
val handler = CoroutineExceptionHandler { _, exception ->
15+
println("Caught $exception with suppressed ${exception.suppressed().contentToString()}")
16+
}
17+
18+
val job = launch(handler + coroutineContext, parent = Job()) {
19+
launch(coroutineContext, start = CoroutineStart.ATOMIC) {
20+
try {
21+
delay(Long.MAX_VALUE)
22+
} finally {
23+
throw ArithmeticException()
24+
}
25+
}
26+
27+
launch(coroutineContext) {
28+
throw IOException()
29+
}
30+
31+
delay(Long.MAX_VALUE)
32+
}
33+
34+
job.join()
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
6+
package kotlinx.coroutines.experimental.guide.exceptions06
7+
8+
import kotlinx.coroutines.experimental.*
9+
import java.io.*
10+
import kotlin.coroutines.experimental.*
11+
12+
fun main(args: Array<String>) = runBlocking {
13+
val handler = CoroutineExceptionHandler { _, exception ->
14+
println("Caught original $exception")
15+
}
16+
17+
val job = launch(handler) {
18+
val inner = launch(coroutineContext) {
19+
launch(coroutineContext) {
20+
launch(coroutineContext) {
21+
throw IOException()
22+
}
23+
}
24+
}
25+
26+
try {
27+
inner.join()
28+
} catch (e: JobCancellationException) {
29+
println("Rethrowing JobCancellationException with original cause")
30+
throw e
31+
}
32+
}
33+
34+
job.join()
35+
}

core/kotlinx-coroutines-core/test/guide/test/GuideTest.kt

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// This file was automatically generated from coroutines-guide.md by Knit tool. Do not edit.
22
package kotlinx.coroutines.experimental.guide.test
33

4-
import org.junit.Test
4+
import org.junit.*
55

66
class GuideTest {
77

@@ -267,6 +267,58 @@ class GuideTest {
267267
)
268268
}
269269

270+
@Test
271+
fun testKotlinxCoroutinesExperimentalGuideExceptions01() {
272+
test("KotlinxCoroutinesExperimentalGuideExceptions01") { kotlinx.coroutines.experimental.guide.exceptions01.main(emptyArray()) }.verifyExceptions(
273+
"Throwing exception from launch",
274+
"Exception in thread \"ForkJoinPool.commonPool-worker-2 @coroutine#2\" java.lang.IndexOutOfBoundsException",
275+
"Joined failed job",
276+
"Throwing exception from async",
277+
"Caught ArithmeticException"
278+
)
279+
}
280+
281+
@Test
282+
fun testKotlinxCoroutinesExperimentalGuideExceptions02() {
283+
test("KotlinxCoroutinesExperimentalGuideExceptions02") { kotlinx.coroutines.experimental.guide.exceptions02.main(emptyArray()) }.verifyLines(
284+
"Caught java.lang.AssertionError"
285+
)
286+
}
287+
288+
@Test
289+
fun testKotlinxCoroutinesExperimentalGuideExceptions03() {
290+
test("KotlinxCoroutinesExperimentalGuideExceptions03") { kotlinx.coroutines.experimental.guide.exceptions03.main(emptyArray()) }.verifyLines(
291+
"Cancelling child",
292+
"Child is cancelled",
293+
"Parent is not cancelled"
294+
)
295+
}
296+
297+
@Test
298+
fun testKotlinxCoroutinesExperimentalGuideExceptions04() {
299+
test("KotlinxCoroutinesExperimentalGuideExceptions04") { kotlinx.coroutines.experimental.guide.exceptions04.main(emptyArray()) }.verifyLines(
300+
"Child throws an exception",
301+
"Children are cancelled, but exception is not handled until children are terminated completely",
302+
"Last child finished its non cancellable block",
303+
"Caught java.lang.ArithmeticException"
304+
)
305+
}
306+
307+
@Test
308+
fun testKotlinxCoroutinesExperimentalGuideExceptions05() {
309+
test("KotlinxCoroutinesExperimentalGuideExceptions05") { kotlinx.coroutines.experimental.guide.exceptions05.main(emptyArray()) }.verifyLines(
310+
"Caught java.io.IOException with suppressed [java.lang.ArithmeticException]"
311+
)
312+
}
313+
314+
@Test
315+
fun testKotlinxCoroutinesExperimentalGuideExceptions06() {
316+
test("KotlinxCoroutinesExperimentalGuideExceptions06") { kotlinx.coroutines.experimental.guide.exceptions06.main(emptyArray()) }.verifyLines(
317+
"Rethrowing JobCancellationException with original cause",
318+
"Caught original java.io.IOException"
319+
)
320+
}
321+
270322
@Test
271323
fun testKotlinxCoroutinesExperimentalGuideChannel01() {
272324
test("KotlinxCoroutinesExperimentalGuideChannel01") { kotlinx.coroutines.experimental.guide.channel01.main(emptyArray()) }.verifyLines(

core/kotlinx-coroutines-core/test/guide/test/TestUtil.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,18 @@ fun List<String>.verifyLinesStartUnordered(vararg expected: String) {
169169
sorted().verifyLinesStart(*expectedSorted)
170170
}
171171

172+
fun List<String>.verifyExceptions(vararg expected: String) {
173+
val actual = filter { !it.startsWith("\tat ") }
174+
175+
val n = minOf(actual.size, expected.size)
176+
for (i in 0 until n) {
177+
val exp = sanitize(expected[i], SanitizeMode.FLEXIBLE_THREAD)
178+
val act = sanitize(actual[i], SanitizeMode.FLEXIBLE_THREAD)
179+
assertEquals("Line ${i + 1}", exp, act)
180+
}
181+
}
182+
183+
172184
fun List<String>.verifyLinesStart(vararg expected: String) {
173185
val n = minOf(size, expected.size)
174186
for (i in 0 until n) {

0 commit comments

Comments
 (0)