Exception handling lets you catch errors and handle them instead of crashing.
Obsługa wyjątków pozwala wychwytywać błędy i je obsługiwać zamiast crashować.
Real programs encounter unexpected situations — files don't exist, network fails, user enters invalid data.
Prawdziwe programy napotykają nieoczekiwane sytuacje — pliki nie istnieją, sieć zawodzi, użytkownik wpisuje nieprawidłowe dane.
Exceptions let you implement fallbacks, retries, alternative paths — not just "stop the program".
Wyjątki pozwalają implementować fallbacki, retry, alternatywne ścieżki — nie tylko "zatrzymaj program".
Documentation:
Video:
Corey Schafer — Try/Except (0:00–25:00)
Create exceptions_demo.py:
Utwórz exceptions_demo.py:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Without exception handling / Bez obsługi wyjątków
# result = 10 / 0 # This crashes! / To crashuje!
# With exception handling / Z obsługą wyjątków
try:
result = 10 / 0
except ZeroDivisionError:
logger.error("Cannot divide by zero")
logger.info("Program continues...")
# Multiple exception types / Wiele typów wyjątków
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
logger.warning("Division by zero")
return None
except TypeError:
logger.warning("Invalid types - need numbers")
return None
print(safe_divide(10, 2))
print(safe_divide(10, 0))
print(safe_divide(10, "x"))Run:
Uruchom:
uv run python exceptions_demo.pyimport logging
logger = logging.getLogger(__name__)
# ValueError
try:
number = int("not_a_number")
except ValueError as e:
logger.error(f"Invalid number: {e}")
# FileNotFoundError
try:
with open("missing.txt") as file:
content = file.read()
except FileNotFoundError:
logger.warning("File not found: missing.txt")
# KeyError
try:
person = {"name": "Alice"}
age = person["age"]
except KeyError as e:
logger.error(f"Key doesn't exist: {e}")import logging
logger = logging.getLogger(__name__)
def read_file(filename: str) -> str | None:
try:
with open(filename, "r") as file:
content = file.read()
except FileNotFoundError:
logger.warning(f"File not found: {filename}")
return None
finally:
logger.debug(f"Finished processing: {filename}")
# Success code outside try block / Kod sukcesu poza blokiem try
logger.info(f"Successfully read: {filename}")
return content
content = read_file("sample.txt")How it works / Jak to działa:
try:— code that might fail / kod który może zawieśćexcept:— handles specific errors / obsługuje konkretne błędyfinally:— always runs, good for cleanup / zawsze się wykonuje, dobre do sprzątania
Note: else clause exists but is rarely used — cleaner to put success code after try/except block.
Uwaga: Klauzula else istnieje ale jest rzadko używana — czytelniej umieścić kod sukcesu po bloku try/except.
Sometimes you want to signal an error in your code.
Czasami chcesz zasygnalizować błąd we własnym kodzie.
import logging
logger = logging.getLogger(__name__)
def validate_age(age: int) -> None:
if age < 0:
raise ValueError("Age cannot be negative")
if age > 150:
raise ValueError("Age unrealistic")
logger.info(f"Valid age: {age}")
try:
validate_age(25)
validate_age(-5)
except ValueError as e:
logger.error(f"Validation error: {e}")Create your own exception classes for specific errors.
Twórz własne klasy wyjątków dla konkretnych błędów.
import logging
logger = logging.getLogger(__name__)
class InsufficientFundsError(Exception):
pass
class BankAccount:
def __init__(self, balance: float):
self.balance = balance
def withdraw(self, amount: float) -> None:
if amount > self.balance:
raise InsufficientFundsError(
f"Cannot withdraw ${amount:.2f}. Balance: ${self.balance:.2f}"
)
self.balance -= amount
logger.info(f"Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
account = BankAccount(100.0)
try:
account.withdraw(50)
account.withdraw(100)
except InsufficientFundsError as e:
logger.error(f"Transaction failed: {e}")from pathlib import Path
import json
import logging
logger = logging.getLogger(__name__)
class SafeFileHandler:
def read_json(self, filename: str) -> dict | None:
try:
path = Path(filename)
if not path.exists():
logger.warning(f"File not found: {filename}")
return None
content = path.read_text()
return json.loads(content)
except json.JSONDecodeError as e:
logger.error(f"Invalid JSON in {filename}: {e}")
raise e
except PermissionError:
logger.error(f"No permission to read {filename}")
return None
def write_json(self, filename: str, data: dict) -> bool:
try:
Path(filename).write_text(json.dumps(data, indent=2))
return True
except Exception:
logger.exception(f"Failed to write {filename}")
return False
# Usage / Użycie
logging.basicConfig(level=logging.INFO)
handler = SafeFileHandler()
data = handler.read_json("person.json")
if data:
print(f"Loaded: {data.get('name')}")Why re-raise? / Dlaczego podnosić ponownie?
raise e after logging lets caller decide what to do — you log the error but don't hide it.
raise e po zalogowaniu pozwala wywołującemu zdecydować co zrobić — logujesz błąd ale go nie ukrywasz.
Stack trace in logs / Stack trace w logach:
try:
result = risky_operation()
except Exception:
logger.exception("Operation failed")
raiseTwo ways to log with stack trace / Dwa sposoby logowania ze stack trace:
-
logger.exception()- automatically includes stack trace, use inexceptblockslogger.exception()- automatycznie dodaje stack trace, używaj w blokachexcept -
logger.error(..., exc_info=True)- manually add stack trace to any log levellogger.error(..., exc_info=True)- ręcznie dodaj stack trace do dowolnego poziomu logowania
Note: Use raise without argument to re-raise original exception with full stack trace.
Uwaga: Użyj raise bez argumentu aby podnieść ponownie oryginalny wyjątek z pełnym stack trace.
Do:
-
Only catch exceptions you can handle
Łap tylko wyjątki które możesz obsłużyć
-
Add meaningful error messages
Dodawaj sensowne komunikaty błędów
Don't:
-
Use bare
except:— it hides bugsUżywaj gołego
except:— ukrywa błędy -
Silence errors without logging
Wyciszaj błędów bez logowania
-
Catch exceptions you can't handle
Nie Łap wyjątków których nie możesz obsłużyć
After this section you can:
Po tej sekcji potrafisz:
-
handle exceptions with try/except
obsługiwać wyjątki z try/except
-
catch specific exception types
łapać konkretne typy wyjątków
-
raise exceptions with meaningful messages
podnosić wyjątki z sensownymi komunikatami
-
create custom exception classes
tworzyć własne klasy wyjątków
-
build robust error handling into programs
budować solidną obsługę błędów w programach
Next: 2.4 — Moduły i importy