CodeRigor

FREE LESSON

Exceptions, resources & honest failures

Narrow exception handling, context-managed streams and preserving failure information in evaluation code.

Exceptions interrupt ordinary control flow until a matching handler is found. Catch the exception you can actually handle, close resources, and let unrelated faults remain visible. A broad except Exception: return 0 can turn a broken evaluator into a plausible zero-error result.

Success and failure paths must both leave the opened context.

Resource lifetime encloses parsing
start / 3
The context closes after success and after a parse error. The error remains visible to the caller.
Resource lifetime encloses parsing
The context closes after success and after a parse error. The error remains visible to the caller.
Python
def parse_count(text):
    try:
        value = int(text)
    except ValueError as exc:
        raise ValueError("count must be an integer") from exc
    if value < 0:
        raise ValueError("count must be nonnegative")
    return value


print(parse_count("3"))

with enters a context and always exits it, including when a read or parse fails. File objects are context managers. try/finally also guarantees cleanup; a return in finally can suppress an exception and should be avoided.

Python
import io

stream = io.StringIO("first\nsecond\n")
with stream as handle:
    print(handle.readline().strip())
print(stream.closed)

Accepting an opener function lets a test inject a string stream or failing context manager. The function under test owns the context it opens. This is useful for local files without requiring real disk fixtures or network calls. We practise the simpler text protocol first; JSONL validation comes later.

An infrastructure failure is different from malformed numeric data and must not become an apparently valid zero score.

Catch only the error you can explain
A conversion ValueError gains row context. An OSError from opening or reading propagates unchanged.
Catch only the error you can explain
A conversion ValueError gains row context. An OSError from opening or reading propagates unchanged.

For the build, blank/comment lines are ignored. Every other line must be a finite float; NaN and infinity parse successfully with float(), so check finiteness explicitly. On a bad value report its 1-based physical line number, and ensure the stream is closed. A read error must propagate; it is not a malformed numeric row and should not silently disappear from the denominator.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Focus on narrow exception handling and finally. The lesson applies these ideas to resource cleanup and preserving the original failure when a helper exits.