PythonMastery

Catch the error you expect, not every error

A bare except hides typos and real bugs behind a friendly message. Catch the one error you expect, keep the try small, and re-raise with from.

except: catches everything: the error you had in mind, the typo you didn't notice, and even Ctrl+C. Code that swallows every error doesn't stop failing; it just stops telling you. Name the error you expect, and let the rest crash loudly where you can see them.

Before

python
def parse_price(text):
    try:
        return float(text.strip().replace("£", ""))
    except:
        return 0.0

print(parse_price("£12.50"))
print(parse_price("twelve"))   # bad input: fine, we expected that
print(parse_price(12.5))       # a bug in the CALLER, silently turned into 0.0
output
12.5
0.0
0.0

The last call passed a number where a string was expected. That's a mistake worth hearing about, and the bare except turned it into a believable price.

After

python
def parse_price(text):
    cleaned = text.strip().replace("£", "")
    try:
        return float(cleaned)
    except ValueError:
        return 0.0

print(parse_price("£12.50"))
print(parse_price("twelve"))
try:
    parse_price(12.5)
except AttributeError as err:
    print("caller bug surfaced:", err)
output
12.5
0.0
caller bug surfaced: 'float' object has no attribute 'strip'

The try now wraps only the one line that can fail in the expected way, and only ValueError is handled.

Add context, keep the cause

When you catch an error to raise a clearer one, chain it with from so the original traceback isn't lost.

python
class ConfigError(Exception):
    pass

def load_port(settings):
    try:
        return int(settings["port"])
    except KeyError as err:
        raise ConfigError("settings has no 'port'") from err

try:
    load_port({"host": "localhost"})
except ConfigError as err:
    print(err, "| caused by:", repr(err.__cause__))
output
settings has no 'port' | caused by: KeyError('port')

Why it works

Every exception is a class, and except ValueError matches only that class and its subclasses. Anything else passes straight through to the traceback, which is exactly where an unexpected error belongs.

When not to use it

At the very top of a long-running program (a web handler, a worker loop) it's reasonable to catch Exception once, log it with the traceback, and carry on to the next job. That's a deliberate safety net, not except: pass. See Errors & Exceptions for how to read the traceback you'd otherwise have hidden.

Learn it properly: Exceptions: Patterns Beyond the Basics, Errors & Exceptions: When Things Go Wrong