Exception Handling
How
dont catch fatal exceptions or unrecoverable errors
Difficult to safely clean up
The application may be in a partially corrupted state.
Memory or state corruption may lead to worse downstream bugs.
Certain exceptiona might be able to be caught
Application should crash
Log everything before crash
Fail fast and restart
For long-running apps (like services), use a watchdog or orchestrator (e.g. Kubernetes, systemd, Windows Service Recovery) to restart the process automatically.
Avoid causing them
Watch recursion depth to prevent stack overflows.
Limit memory usage in large object allocations.
Use safe pointer handling (in unsafe code).
Example
OutOfMemoryException
StackOverflowException
AccessViolationException
Boneheaded Exceptions: Errors due to bugs in the code (programmer errors), such as NullReferenceException.
These should be fixed at the source and can be used to signal misuse in APIs.
Preventable bugs
Avoid catching these
These are bugs not runtime unpredictabliity
Catching and ignoring them hides real defects.
They should be found, fixed, or prevented during development, not handled at runtime.
Vexing Exceptions: Errors that are difficult to predict, like FormatException. Due to poor api design
They should be handled gracefully, often by validating inputs beforehand.
Occuring during normal expected situations
These are common and expected cases, not errors.
Examples
FormatException
FileNotFoundException
InvalidCastException
You often need try/catch, even though you could have avoided the problem with better APIs.
Exogenous Exceptions: External issues, such as network failures.
Implement retry logic and handle these exceptions to maintain system stability.
unpredictable and inevitable in production code
e.g. network failures, file system issues, user input, hardware errors
Anticipate and handle specific exceptions
Recommendations
Validate Inputs:
Always check inputs before processing to prevent errors like IndexOutOfRangeException.
Use defensive programming
Fail fast
When writing libraries or shared code, throw meaningful exceptions for bad inputs
Use Specific Exception Types:
Throw and catch specific exceptions to provide clear error messages and avoid masking issues.
Avoid Swallowing Exceptions:
Catching exceptions without proper handling can lead to silent failures. Always log or address exceptions appropriately.
Use correct log level
Bubble the exception up and make it meaningful to the user
ie use of error handlers to convert into a meaningful message (eg webserver can convert to 503)
Provide Clear Error Messages:
Ensure that exception messages are informative and helpful for debugging.
Add key data, tracing id (to tie several requests in distributed systems), say whats wrong
Implement Retry Logic:
For transient errors, such as network timeouts, implement retry mechanisms to enhance reliability.
Use Static Analysis & Tests
Don’t Let Invalid State Leak
Catch issues before they propagate (e.g., nulls written to DB)
Use of try pattern
instead of try/catch use
Provide fallbacks:
default config, cached data, offline mode.
Log
Logging during exceptions
Always include the exception object, so stack trace is visible
Add context using message templates or parameters
Avoid swallowing the exception without logging
Logging types
ERROR
Something unexpected, serious, or broken happened that needs attention. E.g.:
Unhandled exceptions that break/stop expected workflows.
Failing to connect to a database or critical API.
Data corruption or potential data loss.
WARN
Something went wrong but is recoverable or non-critical. E.g.:
File not found but a fallback is in place.
Third-party service failed but is optional.
Retryable network issues.
INFO
For normal application flow, even when exceptions are expected. E.g.:
User cancels an operation intentionally.
Expected validation failures (e.g., user entered invalid data).
Retry attempts that are expected.
No impact on system stability
Logging messages
Help with debugging and find the issues to then fix it
Dont want to have lots of info (cost to log aggregator and search) or sensitive information (security and privacy issues)
Should have
What Happened
Error description (in your own words, not just the exception type):
E.g., “Failed to process payment” or “Error while updating user profile”.
Describe the action the code was performing when the exception occurred.
Where It Happened
Class/method name (can be implicit from the stack trace, but an explicit label can help).
Who or What It Affected
Inputs or parameters relevant to the operation.
Configuration or flags that might affect behavior.
The Exception Itself
To capture the
Stack trace
Inner exceptions
Message and type
Should not have
Sensitive data (use redaction (obfuscate) or ommision)
Passwords
Credit card numbers
Authentication tokens
Any PII that could compromise user privacy
Vagueness
Too much data, which hides the intent
Alternatives to Exception handling
Try pattern
Result type (monad)
Optional
Validate early
Return values (booleans, nulls, error codes)
ISsues
being slow or a non-local goto statement, making code harder to understand
But Exceptions offer a clear way to handle unexpected situations
But Performance overhead is negligible compared to other bottlenecks (like database queries).
Links
http://tutorials.jenkov.com/exception-handling-strategies/index.html
https://mattburke.dev/talks/youre-doing-exceptions-wrong/
Last updated
Was this helpful?