Error Handling & Robustness

the cost of unchecked errors

Imagine driving with the low-fuel warning light unplugged. Nothing seems wrong - the dashboard looks fine, the car drives normally - right up until you coast to a stop on a motorway, far from a petrol station, with no warning. The danger of an ignored error is not the moment you ignore it; it is the much worse moment, somewhere else entirely, when the consequence finally arrives with the cause long out of sight.

When you do not check a call that failed, the program does not stop - it keeps running on a false assumption. Consider the concrete chain: you call write() to save a file, it returns a short count or -1 because the disk filled, you do not check it, so your program reports 'saved successfully' and the user closes the app. The data is gone, and nobody knows for hours or days. Or: malloc() returns NULL under memory pressure, you do not check, you write through the null pointer, and the program crashes - but the crash is at the dereference, which may be far from and unrelated to the real problem (memory exhaustion). Or worst of all: a failed call leaves a buffer half-initialised, you use it as if it were valid, and the bad data quietly flows into other calculations, getting written to a database, sent over the network, used to make decisions - silent corruption that spreads. The unifying cost is that an unchecked error decouples the symptom from the cause: the program fails (or worse, succeeds wrongly) somewhere distant from where it actually went wrong, which is precisely what makes such bugs so expensive to track down.

Why it matters: this is the concrete answer to 'why bother checking every return value?' The cost is not abstract tidiness - it is data loss, corruption that propagates, and crashes whose location tells you nothing about their cause. The most insidious case is the one with no crash at all: undefined behaviour or a swallowed error can corrupt state silently, so the program keeps running and even appears to work while producing subtly wrong results. The honest framing is that checking errors is cheap insurance against expensive, delayed, hard-to-localise failures - you pay a few lines of if-checks now to avoid a debugging nightmare (and possibly real-world damage) later.

FILE *f = fopen(path, "w"); fprintf(f, "%d\n", value); - if fopen() failed and returned NULL, fprintf() writes through a null FILE pointer: on many systems an immediate crash, with no hint that the real cause was a permission or disk problem at the fopen() call several lines up.

The crash lands at fprintf(), but the real fault was the unchecked fopen() above it.

The worst unchecked errors do not crash at all - they corrupt state silently and the program keeps producing wrong results. 'It ran without crashing' is not evidence that the errors were handled; an ignored failure can sit invisible until it does maximum damage far from its source.

Also called
silent corruptionignored-error consequences默默損壞