Exception Swallowing
Exception Swallowing catches errors and discards them, hiding failures and erasing stack traces so bugs are nearly undebuggable. Catch only what you can handle, fail fast otherwise, and always log with full context.
Exception Swallowing is catching an exception and then doing nothing useful with it — an empty catch {} block, a bare except: pass, or a handler that logs nothing and returns a default. The error is suppressed, so the program continues as if nothing went wrong while the real problem disappears.
Why It Happens
Developers swallow exceptions to make code 'work' under pressure: a checked exception is inconvenient, a noisy error interrupts a demo, or a flaky call occasionally throws. Wrapping it in an empty catch silences the symptom. Broad catches (catch (Exception), except Exception) make it worse by hiding errors the author never anticipated, including programming bugs.
Why It Hurts
Failures become invisible. A method returns null or a default instead of signaling that something broke, so corruption spreads downstream and surfaces far from the cause, often as an unrelated error much later. Stack traces are lost, so when a bug is finally noticed there is no trail to follow. Broad swallowing also hides serious problems — out-of-memory, null dereferences, configuration errors — that should have stopped the program. Debugging turns into guesswork.
Warning Signs
- Empty catch blocks or
except: pass. - Catch blocks that return
null/default with no log and no rethrow. - Catching the broadest exception type 'just in case.'
- Bugs that manifest as missing data or wrong results with no error in the logs.
Better Alternatives
Use structured error handling: catch only the specific exceptions you can actually handle, and handle them meaningfully — recover, retry with backoff, or translate to a domain error. Prefer fail fast for unexpected conditions, letting the error propagate to a boundary that can log and respond. Route errors through centralized logging with full context and stack traces. If you must catch broadly at a top-level boundary, always log before deciding what to do.
How to Refactor Out of It
Search for empty catches and bare excepts. For each, decide whether the code can genuinely recover. If yes, implement real recovery and log at the appropriate level. If no, remove the catch and let the exception propagate, or rethrow it (preserving the original cause) after logging. Narrow broad catches to the specific types you expect. Add a top-level handler that logs uncaught errors with full stack traces. Add tests that assert errors are surfaced rather than silently swallowed.