What to do when data is wrong

Every exception needs a designed response. These are the four available choices.

The right response depends on the business consequence of getting it wrong. A missing optional field is different from a missing required one. A record that fails validation on one field is different from a record that fails on five. The design decision is made per exception type, not once for the whole system.

Choose one per exception type

Four responses, each with a different cost and risk profile

Reject and log: the record is not processed, a detailed error is written to a log, and someone is notified. Best for exceptions where processing a wrong record is worse than not processing it at all. Requires someone to monitor the log and resolve rejections.

Apply a default and continue: the system substitutes a defined default value and processes the record. Best for exceptions where a reasonable default exists and the cost of a slightly wrong record is low. Requires the default to be explicitly defined and reviewed periodically.

Flag for human review: the record is held in a visible queue and a person decides what to do with it. Best for exceptions where the right answer depends on context the system cannot determine. Requires someone to own and clear the queue regularly.

Route to a specific owner: the exception is assigned to a named person or team based on the type of exception. Best for exceptions that require a specific kind of decision or information only one person has. Requires the routing logic to stay current as team structure changes.

What happens without it

The four ways unhandled exceptions become permanent problems.

Workarounds multiply

Each informal exception sets a precedent for the next one.

The first exception is handled informally because it seemed too unusual to design for. The second one is handled the same way because the first one was. Within six months there are twelve exception types, each handled by a different person in a slightly different way, none of them documented, all of them producing different outcomes for what are essentially the same situations.

Workarounds do not stay rare. They multiply. Each one is invisible to the system that was supposed to handle the work, which means they cannot be measured, reviewed, or improved.

Exceptions become load-bearing

Workarounds that seem temporary become permanent dependencies.

An exception is handled manually at launch because the team expects to address it in the next sprint. The sprint comes and goes. The exception is still being handled manually six months later. The person who handles it has refined the process and knows exactly what to do. When that person leaves, the knowledge goes with them.

Load-bearing workarounds are the most dangerous kind because they are invisible in the system. The system appears to be handling the full workload. The workaround is what is actually handling much of it.

Failures are invisible

Exceptions that disappear produce silent failures.

An exception that is neither processed nor routed simply disappears. The record is dropped. The task is not created. The notification is not sent. Nobody knows because there is no log, no queue, no notification. The only signal is the downstream effect: a client who did not receive a follow-up, a deal that was not moved forward, a report that is missing records.

Silent failures are the most expensive kind because the cost compounds before anyone notices. Every day the exception is not handled is another day of the downstream effect accumulating.

Systems cannot be improved

Unmeasured exceptions cannot be reduced.

When exceptions are handled informally and not logged, the exception rate is invisible. Nobody knows how often they occur, which types are most common, or whether the rate is increasing. There is no signal to act on.

A system with designed exception handling produces a log of every exception: what type it was, when it occurred, how it was resolved, and how long resolution took. That log is what makes it possible to reduce the exception rate over time, by identifying the most common types and designing them out of the standard flow.

Which way to fail, and say so

Reject-or-default is a fail-closed-or-fail-open choice. Make it on purpose, and log it.

Two of the four responses are the same decision under different names. "Reject and log" fails closed, it refuses when unsure. "Apply a default" fails open, it proceeds. Which is safer is a property of the specific exception, not a house rule, and the fail-open case has to leave a trace.

Fail closed where a wrong action is expensive. If processing a bad record costs more than pausing it, reject and route it. An irreversible step should never proceed on a guess.

Fail open where lock-out is worse than a slightly-wrong record. A low-stakes field with a sensible default should not halt the whole flow because one value was missing. Match the direction to the blast radius, not to a reflex.

Log every fail-open. Applying a default silently is how an exception path becomes invisible. Record that the default was used, so a run of them is a signal you can see, not a workaround nobody notices.

Bend, do not break. When a dependency the exception path needs is down, degrade to a reduced but working mode, hold the record in the queue, rather than dropping the work because a tool was briefly unavailable.

The design moment

The exception path is not an edge case feature. It is where the system proves it was built for production.

Production runs on the happy path only some of the time, the rest is incomplete data, unusual cases, and steps completed out of order. The systems that hold treated every exception as a first-class design concern, not an afterthought.