Skip to content

An exception in ThreadContextElement.updateThreadContext is impossible to handle properly #4518

@gregsh

Description

@gregsh
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext

fun main() {
    Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
        throwable.printStackTrace() // does not work
    }
    runBlocking(Dispatchers.Default) {
        try {
            withContext(CoroutineName("any")) {
                // try
                withContext(ContextElement(10)) {
                    println("Success!")
                }
                //} catch (e: Exception) {
                //    e.printStackTrace() // the only catch that works
                //}

        }
        } catch (e: Exception) {
            e.printStackTrace() // this catch is not called
        }
    }
}

private val threadLocal = ThreadLocal<Int>()

private class ContextElement(val value: Int) : ThreadContextElement<Int> {
    companion object : CoroutineContext.Key<ContextElement>

    override val key: CoroutineContext.Key<*> get() = ContextElement
    override fun restoreThreadContext(context: CoroutineContext, oldState: Int) {
        threadLocal.set(oldState)
    }

    override fun updateThreadContext(context: CoroutineContext): Int {
        val oldState = threadLocal.get()
        threadLocal.set(value)
        return oldState // <--- implicit NPE here
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions