Back to results for “Diagnostics & Performance”
Java › Exceptions

How would you implement a custom checked exception that requires additional context to be attached as the exception propagates up multiple layers of a call stack, without losing information at each layer?

Advanced

Answer

A common pattern for preserving context across multiple call stack layers involves each layer catching the exception, adding its own relevant contextual information (like which specific record ID was being processed when the failure occurred), and rethrowing either the same exception (after mutating/adding to accumulated context, if the exception type supports that) or a new wrapping exception with the original preserved as the cause -- accumulating context this way at each layer (rather than only having the innermost, most technical error message) produces a much more actionable end-to-end error trail when the exception is eventually logged or displayed, letting an on-call engineer understand not just what technically failed but the full business-level context of what the system was attempting to do when it failed.
public class BatchProcessingException extends Exception {
    private final List<String> processingContext = new ArrayList<>();

    public BatchProcessingException(String message, Throwable cause) { super(message, cause); }

    public BatchProcessingException addContext(String context) {
        processingContext.add(context);
        return this;
    }
}

// Layer 1 (innermost): throws with initial context
// Layer 2: catches, adds "processing batch #47" context, rethrows the SAME exception instance
// Layer 3: catches, adds "nightly reconciliation job" context, logs full accumulated context chain
Real-world example A nightly batch reconciliation job's failure log entry shows not just the low-level technical error (a specific database constraint violation) but also the full accumulated business context ("processing batch #47, record #1523, nightly reconciliation job run at 2am"), added incrementally as the exception propagated up through each processing layer, dramatically speeding up the on-call engineer's root-cause diagnosis compared to a bare technical error message alone.

Common follow-ups: What's the trade-off of mutating and rethrowing the same exception instance versus wrapping in a new exception at each layer?;How do structured logging frameworks (like using MDC - Mapped Diagnostic Context) provide an alternative way to accumulate this same contextual information?