Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is catching Exception an anti-pattern in kotlin coroutines?

Stack traces are not very useful in a coroutine environment, which makes the exception type and message extremely important. Exceptions thrown by third party libraries may have very generic types and messages, making it impossible to understand where the code that caused the exception is.[1]

A common way to attach a more context specific message to an exception is to catch and rethrow the exception:

try { ... } catch (e: Exception) { throw RuntimeException("unique message", e) }

This is a well known anti-pattern in a coroutine, because of the special exception type CancellationException which must not be accidentally swallowed.

This leaves the question, should the following be considered an anti-pattern or is it completely fine?

try {
   ...
} catch (e: CancellationException) {
   throw e
} catch (e: Exception) {
   throw RuntimeException("unique message", e)
}

[1] io.grpc.StatusException when using the kotlin coroutines grpc client API is a good example - the stack trace is very generic and does not contain any user created functions.

like image 855
tonicsoft Avatar asked Sep 06 '25 03:09

tonicsoft


1 Answers

This is what I do in my code and I never saw any reason to stop. As a precedent in Java, the need for exception translation is well-recognized and recommended by authoritative sources such as Effective Java.

One particular example is relevant: say your method declares no checked exceptions, but you call into some API that does. You want to wrap such an exception, but don't want to redundantly wrap unchecked ones. You end up writing almost the same idiom as you show here.

like image 136
Marko Topolnik Avatar answered Sep 07 '25 16:09

Marko Topolnik