withSuppression

Wraps an existing handler with suppression such that any invocation of tryCatch within block lambda is combined into a single UncaughtException, which is then propagated to the current handler (if there even was an UncaughtException).

If SuppressedHandler reference is leaked outside the withSuppression lambda, the UncaughtException will be passed back to the originating non-suppressed Handler.

Nested calls of withSuppression will use the root SuppressedHandler, so all tryCatch invocations are propagated to a root exception and added as a suppressed exception.

e.g.

myHandler.withSuppression {
    val suppressed = this

    withSuppression {
        val nested = this
        assertEquals(suppressed, nested)
    }
}

Great for loops and stuff.

e.g.

myHandler.withSuppression {
    // demonstration purposes
    val suppressedHandler = this

    jobs.forEach { job ->

        // Any UncaughtException generated by tryCatch
        // will be added as a suppressed exception to
        // the first UncaughtException.
        tryCatch(context = job) { job.cancel(null) }
    }

    // on lambda closure the single UncaughtException
    // (if there is one) will be passed back to
    // myHandler
}

NOTE: If Handler is null, block is still invoked and the UncaughtException (if there is one) is thrown on lambda closure.