Errors

Exceptions

Use try, except, else, and finally to separate success, recovery, and cleanup.

When no exception is raised, the else block runs. Keeping success in else makes the try block contain only the operation that might fail.

Source

def parse_int(text):
    return int(text)

text = "42"
try:
    number = parse_int(text)
except ValueError:
    print(f"{text}: invalid")
else:
    print(f"{text}: {number}")
finally:
    print(f"checked {text}")

Output

42: 42
checked 42
try, except, else, and finally as parallel lanes; a single coral path traces what actually runs.

When parsing fails, int() raises ValueError. Catching that specific exception makes the expected recovery path explicit.

Source

text = "python"
try:
    number = parse_int(text)
except ValueError:
    print(f"{text}: invalid")
else:
    print(f"{text}: {number}")
finally:
    print(f"checked {text}")

Output

python: invalid
checked python

Bare except: and broad except Exception: swallow far more than the failure you meant to handle, including KeyboardInterrupt (bare) and most programming bugs (broad). The two functions look interchangeable on good input — the divergence appears on a buggy call: passing a list is a programming error, yet the broad version converts it into a quiet None while the specific version lets the TypeError surface.

Source

def safe_parse_broken(text):
    try:
        return int(text)
    except Exception:
        return None

def safe_parse_fixed(text):
    try:
        return int(text)
    except ValueError:
        return None

print(safe_parse_broken("42"))
print(safe_parse_fixed("42"))
print(safe_parse_broken(["4", "2"]))

try:
    safe_parse_fixed(["4", "2"])
except TypeError as error:
    print(type(error).__name__)

Output

42
42
None
TypeError

Notes

See also

Run the complete example

Example code

Expected output

42: 42
checked 42
python: invalid
checked python
42
42
None
TypeError

Execution time appears here after you run the example.