Preventing Exceptions from 3rd party component from crashing the entire application
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
If a third-party component can throw exceptions that bring down your whole application, the real problem is not the exception itself. The problem is that the component has no containment boundary. Good application design assumes external code can fail and limits the damage through wrapping, logging, fallback behavior, and sometimes process isolation.
Put a Safety Boundary Around the Component
The first step is simple: never let unknown third-party code run directly through critical application flow without a boundary.
A wrapper service in C# might look like this:
This does not magically fix the component, but it prevents an exception from tearing through the rest of the request path unchecked.
Decide on a Failure Policy
Catching the exception is only half the job. You also need to decide what the application should do next.
Common choices are:
- return a fallback value
- disable one feature while keeping the rest of the app alive
- retry if the failure is transient
- surface a controlled error to the user
For example, a search suggestion provider may fail while the main page still loads successfully. That is a good place for graceful degradation rather than a full crash.
Log Enough to Debug Later
A swallowed exception with no logging is just a hidden outage. At minimum, log:
- the component name
- the exception type
- the operation that failed
- enough context to reproduce the issue safely
Example:
This gives operators a way to trace failures without exposing internal exception details to end users.
Use Retries Carefully
Retries are useful only for transient failures such as network hiccups or temporary service unavailability. They are not a cure for deterministic bugs inside the component.
A simple retry loop:
Use this only when repeated attempts have a reasonable chance of succeeding.
Isolate Dangerous Components
If the third-party code is unstable enough to corrupt process state, leak memory, or crash the runtime, a try/catch inside the same process may not be enough. In that case, isolate it behind a separate process, worker, or service boundary.
Examples:
- run it in a background worker process
- call it through a separate microservice
- execute it through a supervised job runner
Process isolation is especially important for native libraries or plugins that can crash the host process rather than just raise a managed exception.
Use Circuit Breakers for Repeated Failure
If a dependency fails repeatedly, calling it again on every request can keep hurting the entire application. A circuit breaker stops repeated calls for a period and lets the rest of the app degrade gracefully.
Conceptually:
- failures exceed a threshold
- the circuit opens
- requests skip the component temporarily
- the app retries later to see if recovery happened
This pattern is common for third-party APIs, payment providers, and remote data sources.
Protect Critical Transactions
Some failures are not just about crashes. They can leave your system half-updated. If the third-party component participates in important workflows, guard state changes carefully:
- commit database work only after the component succeeds
- use idempotent operations where possible
- record failed attempts for later repair
Exception containment and data consistency need to be designed together.
Common Pitfalls
The biggest pitfall is wrapping third-party code in a broad catch block and doing nothing. That prevents a crash, but it also destroys observability.
Another common mistake is retrying every exception. A parsing bug or invalid input will not improve on the third attempt.
People also often assume managed exceptions are the only failure mode. Native code, memory corruption, and process termination may require stronger isolation than a simple wrapper method.
Finally, do not let fallback logic hide real incidents forever. Graceful degradation is good, but it should still trigger alerts and investigation.
Summary
- Put a clear exception boundary around third-party components.
- Decide how the application should degrade when the component fails.
- Log failures with enough context to debug them later.
- Retry only transient failures, not deterministic bugs.
- Isolate truly dangerous components in separate processes or services when needed.
Related reading
- Print current call stack from a method in code
- Print Entry, CFBundleIdentifier, Does Not Exist
- Printing not being logged by Kubernetes
- Printing test execution times and pinning down slow tests with py.test
- Printing the loss during TensorFlow training
- Private Network with IPFS not working
- Problem pulling images when running private docker registry inside of Kubernetes
- problem with couchdb remote replication ubuntu local CentOS remote
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.