Error Handling
Error handling is the cross-cutting discipline of anticipating failures, distinguishing transient from permanent errors, retrying the recoverable ones with backoff, circuit-breaking the persistent ones, and always defaulting to a fail-safe state.
Quick answer: Error handling is the cross-cutting discipline of anticipating failures, distinguishing transient from permanent errors, retrying the recoverable ones with backoff, circuit-breaking the persistent ones, and always defaulting to a fail-safe state.
In simple words
In trading, things fail constantly, a request times out, an API rejects an order, data arrives malformed. Error handling is deciding, for each kind of failure, what to do: retry it, give up on it, or stop everything. The golden rule is fail safe: when in doubt, do the cautious thing, which usually means not trading, rather than guessing.
Purpose
Unhandled errors in a trading system do not just crash, they can leave orders in unknown states, positions unmanaged, or the system trading on bad assumptions. Deliberate error handling is what keeps failures contained and safe instead of compounding.
Professional explanation
Transient versus permanent errors
The first and most important distinction is whether an error is transient (temporary, likely to succeed if retried) or permanent (a retry will always fail). Transient errors include network timeouts, rate-limit responses, and 5xx server errors, retrying after a pause often works. Permanent errors include a malformed request, insufficient funds, an invalid instrument, or an authentication failure, retrying is pointless and can be harmful. Misclassifying the two is a classic bug: retrying a permanent error spams the broker and wastes time, while giving up on a transient one abandons a recoverable action. Every error path should be explicitly categorised, and unknown errors should be treated conservatively, often as non-retryable and escalated, rather than blindly retried.
Retries and exponential backoff
Transient errors are retried, but naively retrying immediately and forever makes things worse, it hammers a struggling service and can trip rate limits. The robust pattern is exponential backoff with jitter: wait a short interval, then double it on each attempt (1s, 2s, 4s...), adding randomness so many clients do not retry in lockstep, up to a maximum number of attempts and a total time cap. After the cap, stop and escalate rather than retry forever. Crucially, retries are only safe if the operation is idempotent, retrying an order placement without a client order id can double-send, so retry logic and idempotency must be designed together. Retry the send, but make the send safe to repeat.
Circuit breaking
When a dependency is failing persistently, continuing to call it (even with backoff) wastes resources and delays recognising the outage. A circuit breaker tracks the failure rate of a dependency and, once failures cross a threshold, trips open, short-circuiting further calls for a cooldown period and failing fast instead of hanging on timeouts. After the cooldown it goes half-open, allowing a trial call, and closes again if that succeeds. In a trading system this prevents a flaky broker API from tying up the whole system in retries and makes the outage explicit, so the system can take a deliberate safe action (pause trading, alert) rather than degrade slowly. It converts a slow, ambiguous failure into a fast, clear one.
Fail-safe defaults
The overriding principle of trading error handling is fail-safe: when an error leaves the outcome uncertain, choose the action that cannot make things worse, which almost always means do not trade. If a risk check cannot complete, block the order. If the P&L feed is down, halt new risk. If a data value is missing, do not compute a signal on a guess. This is the opposite of typical web-app error handling, which often defaults to proceeding; in trading, proceeding on a bad assumption can lose real money, so the default must be caution. Failing safe also means preferring a known-safe halt over a clever recovery that might be wrong, the cautious inaction is reversible, a wrong order is not.
Error handling across the order lifecycle
Errors around orders are the most consequential because of ambiguity. The dangerous case is an order request that times out, you do not know if it was received, so you cannot simply retry (might duplicate) or ignore it (might have filled). The correct handling is to query the order's status by its client order id and reconcile before deciding, exactly the idempotency-plus-reconciliation machinery the OMS provides. Similarly, a rejected order must be classified, an insufficient-margin reject is permanent (do not retry, alert), while a transient venue error may be retryable. Error handling here is inseparable from the OMS: the two together turn unreliable order APIs into correct behaviour.
How error handling itself fails
Error handling fails by swallowing errors silently (a bare catch that logs nothing and continues, hiding a problem until it compounds), by retrying permanent errors forever, by retrying non-idempotent operations and duplicating side effects, by failing open (proceeding when uncertain), and by catching too broadly so a real bug is masked as a handled error. A subtle failure is the empty catch that returns a default value, code that on error returns a position of zero or a price of the last value can make the system act on a fabricated number. Robust handling logs every error with context, classifies it, and either recovers safely or fails safe loudly, never silently.
Observability
Errors are signals, so they must be visible. Log every error with its type, context, and the decision taken (retried, given up, circuit-broken, halted), and emit metrics for error rates by type and dependency, retry counts, and circuit-breaker state. A rising error rate is often the earliest warning of trouble, sometimes before any limit is breached, so error-rate alerting is a frontline monitor. Track how often retries succeed versus exhaust, because retries that always exhaust indicate a persistent problem masquerading as transient. The aim is that no error is silent: every failure either recovers cleanly with a trace or escalates to a human, and the pattern of errors is itself monitored as a health signal.
Transient vs permanent errors
| Aspect | Transient error | Permanent error |
|---|---|---|
| Examples | Timeout, rate limit, 5xx | Bad request, insufficient funds, auth failure |
| Right response | Retry with backoff | Do not retry; alert |
| Retrying helps? | Often yes | Never; may harm |
| Underlying cause | Temporary condition | Structural problem |
| If unsure | Treat conservatively, escalate | Treat conservatively, escalate |
Practical example
Illustrative example (Indian market)
A Nifty bot places an order and the broker call times out. Rather than blindly retrying (which could double the order) or ignoring it (which could leave a fill unmanaged), the error handler classifies the timeout as ambiguous and queries the order status by its client order id: the broker reports the order was not received, so it safely retries the same idempotent request. Later, a websocket data message arrives malformed; the handler does not compute a signal on a guessed value, it flags the bad data, skips the bar, and fails safe by holding position. When the broker's API starts returning repeated 5xx errors, a circuit breaker trips after several failures, stops hammering the API, alerts the operator, and the system pauses new risk until the dependency recovers, converting a slow degradation into a clear, safe halt.
Indian broker APIs commonly return rate-limit and transient errors during the first minutes after 9:15 when order volume spikes; handling these with exponential backoff and jitter (rather than immediate uniform retries that worsen the congestion) plus idempotent order ids is what keeps a bot from either missing the open or double-sending orders in that busy window.
Advantages
- Contains failures so they do not compound into unmanaged positions or losses
- Retries with backoff recover from the many genuinely transient failures
- Circuit breaking turns slow, ambiguous outages into fast, clear, safe halts
- Fail-safe defaults ensure uncertainty leads to caution, not a risky guess
Limitations
- Misclassifying transient vs permanent leads to harmful retries or premature give-ups
- Retries are only safe if operations are idempotent, which must be engineered
- Overly conservative fail-safe halting can pause trading on minor, recoverable issues
- Good error handling adds code and paths that themselves must be tested
Why it matters in practice
- The gap between a robust and a fragile system is largely how it handles errors
- Fail-safe defaults are what keep an uncertain failure from becoming a loss
Common mistakes
- Silently swallowing errors in a bare catch that logs nothing and continues
- Retrying a permanent error like insufficient funds forever instead of alerting
- Retrying a non-idempotent order send after a timeout and double-sending
- Returning a fabricated default (zero position, last price) on error and acting on it
- Failing open, proceeding to trade when a check or a feed is uncertain
- Catching too broadly so a real bug is masked as a handled, ignored error
Professional usage
Robust trading systems treat error handling as a first-class design concern, not an afterthought of try/except. They classify every failure as transient or permanent, retry transients with jittered exponential backoff and a cap, wrap flaky dependencies in circuit breakers, and pair all retries with idempotency so nothing is duplicated. Above all they fail safe: uncertainty defaults to not trading, ambiguous order outcomes are resolved by status query and reconciliation, and no error is swallowed silently. Error rates are monitored as an early-warning health signal, and error paths are tested as deliberately as the happy path.
Key takeaways
- Classify errors as transient (retry with backoff) or permanent (do not retry; alert)
- Pair retries with idempotency so retrying can never double-send an order
- Use circuit breakers to fail fast on persistent outages instead of hanging
- Default to fail-safe: when uncertain, do not trade, and never swallow errors silently
Frequently asked questions
What is error handling in a trading system?
What is the difference between a transient and a permanent error?
What is exponential backoff?
Why is idempotency important for retries?
What is a circuit breaker in error handling?
What does fail-safe mean in trading?
How should I handle an order that times out?
Why is failing safe different from typical web app error handling?
What is wrong with swallowing errors silently?
How do I handle a rejected order?
Should unknown errors be retried?
How do circuit breakers and retries work together?
How does error handling relate to monitoring?
Can error handling be too conservative?
Voice search & related questions
Natural-language questions people ask about Error Handling.
What is error handling in a trading bot?
What is the difference between a temporary and a permanent error?
What is exponential backoff?
Why can retrying an order be dangerous?
What should a bot do when it is not sure what happened?
Why is silently ignoring errors bad?
Sources & references
Last reviewed 11 July 2026. Educational content only — not investment advice. Markets and rules change; verify current conventions with SEBI, NSE/BSE and your broker.