Menu
Coddy logo textTech

Czym jest obsługa wyjątków?

Obsługa wyjątków to sposób, w jaki program reaguje na błędy pojawiające się w trakcie działania. Kod, który może zawieść, trafia do chronionego bloku, takiego jak try, a gdy zostanie zgłoszony błąd, sterowanie przeskakuje do procedury obsługi, takiej jak except albo catch, zamiast przerwać program.

Autor: Kevin Spektor, Współzałożyciel i CTO

Aktualizacja: 24 września 2026

Program, który pyta ludzi o wiek, prędzej czy później dostanie "twenty" zamiast 20. Konwersja takiego tekstu to błąd wykonania: int("twenty") zgłasza ValueError, a bez planu na taką sytuację program się zatrzymuje. Obsługa wyjątków to właśnie taki plan. Oznaczasz kod, który może zawieść, i piszesz kod, który wykona się, jeśli tak się stanie.

Next year you will be 35
Not a number: twenty
Next year you will be 20
Done

Zła odpowiedź zostaje zgłoszona, a pętla przechodzi do następnej. Bez try program wyświetliłby jedną linię, a potem traceback.

Jak działa obsługa wyjątków

  1. Kod wewnątrz try wykonuje się normalnie.
  2. Jakaś operacja się nie udaje, a środowisko uruchomieniowe zgłasza wyjątek: obiekt z typem (ValueError) i komunikatem (invalid literal for int() with base 10: 'twenty').
  3. Blok try zatrzymuje się na tej linii. Pozostałe linie są pomijane, dlatego dla "twenty" nie wyświetla się "Next year you will be".
  4. Środowisko porównuje typ wyjątku z każdą klauzulą except, od góry do dołu, i uruchamia pierwszą pasującą.
  5. Gdy procedura obsługi się skończy, program kontynuuje od pierwszej linii po całej instrukcji try.
  6. Jeśli żadna klauzula nie pasuje, wyjątek opuszcza bieżącą funkcję, a szukanie trwa dalej w funkcji, która ją wywołała, potem w funkcji wywołującej tamtą. Nazywa się to zwijaniem stosu wywołań. Jeśli szukanie dojdzie do samej góry programu bez dopasowania, program kończy się tracebackiem.

Krok 6 oznacza, że procedura obsługi nie musi być w funkcji, w której wystąpił błąd. Tutaj awaria następuje dwa wywołania głębiej, a procedura obsługi na dole i tak ją łapie:

parsing 4.50
parsing free
Could not add the prices: could not convert string to float: 'free'

float("free") zawiodło wewnątrz parse_price. Ani parse_price, ani total nie miały procedury obsługi, więc obie zostały porzucone, a "3.20" nigdy nie zostało sparsowane. To główna decyzja projektowa, jaką daje obsługa wyjątków: obsłuż błąd tam, gdzie wiesz, co z nim zrobić, a to często jest daleko od miejsca, w którym się pojawił.

try, except, else i finally

Instrukcja try w Pythonie ma jeszcze dwie opcjonalne części. else wykonuje się tylko wtedy, gdy blok try zakończył się bez wyjątku. finally wykonuje się w każdym przypadku: po sukcesie, po obsłużonym wyjątku, a nawet wtedy, gdy funkcja zwraca wartość z wnętrza try.

no error
finally runs either way
2.0
b was zero
finally runs either way
None

finally to miejsce na sprzątanie: zamknięcie pliku, zwolnienie blokady, zamknięcie połączenia z bazą danych. W Pythonie instrukcja with robi takie sprzątanie dla plików automatycznie i to ona jest zwykle wybierana w ich przypadku.

Zgłaszanie własnych wyjątków

Wyjątki nie służą tylko do błędów wykrywanych przez język. Gdy twoja własna funkcja dostanie dane, z którymi nie może pracować, może zgłosić wyjątek, żeby odmówić, a wywołujący zdecyduje, co dalej. Zdefiniowanie małej klasy wyjątku daje błędowi nazwę, która go opisuje.

70
Refused: cannot take 250, balance is 100

Python używa raise. Java, C++ i JavaScript używają do tego samego throw.

Obsługa wyjątków w innych językach

JęzykSłowa kluczoweWarto wiedzieć
Pythontry, except, else, finally, raiseKażdy wyjątek to obiekt dziedziczący po BaseException
Javatry, catch, finally, throw, throwsWyjątki kontrolowane, takie jak IOException, trzeba złapać albo zadeklarować przez throws
C++try, catch, throwBrak finally; destruktory sprzątają podczas zwijania stosu
JavaScripttry, catch, finally, throwBłędy w kodzie async łapie się przez try wokół await
CbrakFunkcje zwracają kod błędu, a wiele z nich ustawia errno
Gobrak dla zwykłych błędówFunkcje zwracają wartość error, którą sprawdza wywołujący

Ten sam przykład z parsowaniem w Javie wygląda tak:

try {
    int age = Integer.parseInt("twenty");
    System.out.println(age + 1);
} catch (NumberFormatException e) {
    System.out.println("Not a number: " + e.getMessage());
} finally {
    System.out.println("done");
}

Java dzieli wyjątki na dwie grupy. Wyjątki kontrolowane (checked), takie jak IOException, opisują problemy poza kontrolą programu, a kompilator odmawia zbudowania kodu, który ich ani nie łapie, ani nie deklaruje. Wyjątki niekontrolowane (unchecked), czyli podklasy RuntimeException takie jak NullPointerException, zwykle oznaczają błąd w kodzie, a kompilator nie zmusza do ich obsługi.

Częste błędy

  • Łapanie wszystkiego. Gołe except: w Pythonie łapie też KeyboardInterrupt, więc Ctrl+C przestaje działać, a except Exception: łapie błędy, których nigdy nie planowano. Łap konkretny typ, który umiesz obsłużyć.
  • Połykanie błędu. except ValueError: pass ukrywa problem. Co najmniej wyświetl albo zapisz w logach, co poszło nie tak.
  • Za duży blok try. Otaczaj tylko te linie, które mogą zgłosić łapany wyjątek, żeby niezwiązany błąd nie został obsłużony przez pomyłkę.
  • Łapanie błędów zamiast ich naprawiania. IndexError z pętli, która wykonuje o jeden krok za dużo, to błąd w kodzie. Obsługiwanie go utrzymuje zły kod przy życiu.
  • Oczekiwanie, że catch zatrzyma awarię w C albo C++. Błąd segmentacji to sygnał od systemu operacyjnego, a nie wyjątek, i w Linuksie oraz macOS catch (...) w C++ nigdy go nie zobaczy.

Co dalej

Błędy, na które reaguje obsługa wyjątków, opisuje strona o błędzie wykonania, a awarię, której nie da się złapać, strona o błędzie segmentacji. Pełną składnię znajdziesz w przewodnikach po wyjątkach w Pythonie, try i catch w Javie, wyjątkach w C++ i try i catch w JavaScripcie. Kurs Java i kurs Python ćwiczą je na prawdziwych zadaniach.

Najczęściej zadawane pytania

Jakie jest 5 słów kluczowych obsługi wyjątków w Javie?
try, catch, finally, throw i throws. try oznacza obserwowany kod, catch obsługuje konkretny typ wyjątku, a finally uruchamia kod sprzątający bez względu na to, czy wyjątek wystąpił. throw zgłasza wyjątek, a throws w sygnaturze metody deklaruje, które wyjątki kontrolowane metoda może przekazać wywołującemu.
Czym jest obsługa wyjątków w C++?
C++ używa try, catch i throw. Rzucić można dowolny typ, ale zgodnie z konwencją rzuca się obiekt dziedziczący po std::exception, na przykład std::runtime_error, i łapie go przez referencję: catch (const std::exception& e). C++ nie ma finally; sprzątanie odbywa się w destruktorach, które uruchamiają się automatycznie podczas zwijania stosu.
Czym różni się błąd od wyjątku?
W codziennym użyciu błąd to wszystko, co idzie nie tak, a wyjątek to obiekt, którym język ten problem zgłasza. Java rysuje ostrzejszą granicę: Exception obejmuje problemy, które program może rozsądnie obsłużyć, a Error, na przykład OutOfMemoryError albo StackOverflowError, sygnalizuje awarię JVM, której program zwykle nie powinien próbować łapać. W Pythonie ValueError i ZeroDivisionError to wyjątki, mimo że w nazwie mają słowo Error.
Czym różni się throw od throws w Javie?
throw to instrukcja, która zgłasza jeden wyjątek w danym miejscu: throw new IllegalArgumentException("negative age");. throws to część deklaracji metody, która wymienia wyjątki kontrolowane, jakie metoda może przekazać wywołującemu: void load() throws IOException. Kompilator wymaga wtedy, żeby każdy wywołujący albo złapał ten wyjątek, albo też go zadeklarował.
Czy obsługa wyjątków spowalnia kod?
Wejście do bloku try jest tanie w większości nowoczesnych języków. Od Pythona 3.11 try nie kosztuje prawie nic, gdy żaden wyjątek nie zostaje zgłoszony, a główne kompilatory C++ nie dodają kosztu w czasie wykonania na ścieżce, na której nic nie jest rzucane. Zgłoszenie i złapanie wyjątku jest dużo wolniejsze niż test if, więc w pętlach krytycznych dla wydajności sprawdzaj typowe przypadki zamiast polegać na wyjątkach.
Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ