sentry-java
sentry-java copied to clipboard
Support SentryCoroutineExceptionHandler
As we have a sentry-kotlin-extensions module right now and SentryContext for Coroutines, it'd be a nice addition offering a SentryCoroutineExceptionHandler, https://kotlinlang.org/docs/exception-handling.html#coroutineexceptionhandler
so people can use it and when it throws, it captures an event automatically, how does that sound?
Similar to our UncaughtExceptionHandlerIntegration
val handler = SentryCoroutineExceptionHandler { _, exception ->
// ideally we create an event with a mechanism
Sentry.captureException(exception)
}
val job = GlobalScope.launch(handler) {
throw AssertionError()
}
examples can be found on https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/jvm/test/guide example-exceptions-{number}-kt files
works like a try/catch, if no CoroutineExceptionHandler is given, UncaughtExceptionHandlerIntegration gets called and crashes the App, but if a CoroutineExceptionHandler is given, it gets caught and swallowed, so its a bit less boilerplate than a try/catch but works the same way
one thing to note is:
[CoroutineExceptionHandler] can be invoked from an arbitrary thread
so we cannot use the current thread when creating a ExceptionMechanismException
public object SentryCoroutineExceptionHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler), CoroutineExceptionHandler {
override fun handleException(context: CoroutineContext, exception: Throwable) {
val mechanism = Mechanism().apply {
// null and true is the same
// isHandled = true
type = "CoroutineExceptionHandler"
}
// cannot use the Thread.currentThread()
// [CoroutineExceptionHandler] can be invoked from an arbitrary thread
// ExceptionMechanismException should have an overload without a thread
val error = ExceptionMechanismException(mechanism, exception, Thread.currentThread())
val event = SentryEvent(error)
// we probably need a hint here to not append anything from the `currentThread`
Sentry.captureEvent(event)
}
}
GlobalScope.launch(SentryCoroutineExceptionHandler) {
throw AssertionError()
}
related topic https://kt.academy/article/cc-exception-handling
Consider testing https://github.com/Anamorphosee/stacktrace-decoroutinator and adding to the docs if it gives better stack traces
Relates to https://github.com/getsentry/sentry-java/issues/2687 as well