我正在密集地使用协程来创建服务,但我面临着一个将异常从我的服务内部转换到外部的问题.以下是我想在没有Coroutine的情况下做的综合(here is the full example in a playground:
class MyService {
fun myBigComputation(type: MyServiceType) {
try {
for (i in (0..10_000)) {
mySubComputation(type, i)
}
} catch (e: LowLevelException) {
throw HighLevelException(type, e)
}
}
private fun mySubComputation(type: MyServiceType, i: Int) {
...
// something bad happend
throw LowLevelException(type)
}
...
}
你可以看到我正在把LowLevelException改成HighLevelException.在日常生活中,最好的方法是什么?
That is not working as LowLevelException fails all the structure until the supervisorScope Playground
suspend fun main() = coroutineScope {
val service = MyService()
supervisorScope {
for (type in MyService.MyServiceType.values()) {
launch(CoroutineExceptionHandler { _, e ->
if (e is HighLevelException) {
println("ERROR: ${e.message}")
}
}) {
service.myBigComputation(type)
}
}
}
}
class MyService {
suspend fun myBigComputation(type: MyServiceType) = coroutineScope {
launch(CoroutineExceptionHandler { _, e ->
if (e is LowLevelException) {
throw HighLevelException(type, e)
}
}) {
for (i in (0..10)) {
mySubComputation(type, i)
}
}
}
private fun mySubComputation(type: MyServiceType, i: Int) {
if (i < 5 || type != MyServiceType.type1) {
print(".")
} else {
// something bad happend
println("something bad happened but exception kill all")
throw LowLevelException(type)
}
}
class LowLevelException(val type: MyServiceType): Exception()
enum class MyServiceType {
type1,
type2,
type3
}
}
class HighLevelException(val type: MyService.MyServiceType, e: Exception): Exception("Exception for type $type", e)
I did that, but I'm pretty sure that there is a better way, no ? Playground
suspend fun main() = coroutineScope {
val service = MyService()
supervisorScope {
for (type in MyService.MyServiceType.values()) {
launch(CoroutineExceptionHandler { _, e ->
if (e is HighLevelException) {
println("ERROR: ${e.message}")
}
}) {
service.myBigComputation(type)
}
}
}
}
class MyService {
suspend fun myBigComputation(type: MyServiceType) = supervisorScope {
launch(CoroutineExceptionHandler { _, e ->
if (e is LowLevelException) {
throw HighLevelException(type, e)
}
}) {
for (i in (0..10)) {
mySubComputation(type, i)
}
}
}
//...
}