Menu
Coddy logo textTech

Что такое обработка исключений?

Обработка исключений это способ, которым программа реагирует на ошибки, возникающие во время её работы. Код, который может дать сбой, помещают в защищённый блок, например try, и когда возникает ошибка, управление переходит к обработчику, например except или catch, а программа не падает.

Автор: Kevin Spektor, Сооснователь и CTO

Обновлено 24 сентября 2026 г.

Программа, которая спрашивает у людей возраст, рано или поздно получит «twenty» вместо 20. Преобразование такого текста приводит к ошибке времени выполнения: int("twenty") выбрасывает ValueError, и если на этот случай нет плана, программа останавливается. Обработка исключений и есть такой план. Ты отмечаешь код, который может дать сбой, и пишешь код, который выполнится, если сбой произойдёт.

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

О плохом ответе сообщается, и цикл переходит к следующему. Без try программа вывела бы одну строку, а за ней traceback.

Как работает обработка исключений

  1. Код внутри try выполняется как обычно.
  2. Операция не удаётся, и среда выполнения выбрасывает исключение: объект с типом (ValueError) и сообщением (invalid literal for int() with base 10: 'twenty').
  3. Блок try останавливается на этой строке. Оставшиеся его строки пропускаются, поэтому для «twenty» не выводится «Next year you will be».
  4. Среда выполнения сравнивает тип исключения с каждым блоком except сверху вниз и выполняет первый подходящий.
  5. Когда обработчик заканчивает работу, программа продолжается с первой строки после всей инструкции try.
  6. Если ни один блок не подошёл, исключение покидает текущую функцию, и поиск продолжается в функции, которая её вызвала, затем в той, что вызвала её. Это называется раскруткой стека вызовов. Если поиск доходит до верха программы и ничего не находит, программа завершается с traceback.

Из шага 6 следует, что обработчик не обязан находиться в той функции, где происходит ошибка. Здесь сбой случается на глубине двух вызовов, и обработчик внизу всё равно его перехватывает:

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

float("free") не сработал внутри parse_price. Ни у parse_price, ни у total обработчика не было, поэтому обе функции были прерваны, и «3.20» так и не разобрано. Это главный выбор, который даёт обработка исключений: обрабатывать ошибку там, где ты знаешь, что с ней делать, а это часто далеко от места, где она произошла.

try, except, else и finally

У инструкции try в Python есть ещё две необязательные части. else выполняется, только если блок try завершился без исключения. finally выполняется в любом случае: после успеха, после обработанного исключения и даже когда функция возвращает значение изнутри try.

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

В finally помещают освобождение ресурсов: закрытие файла, снятие блокировки, закрытие соединения с базой данных. В Python инструкция with делает это для файлов автоматически, и для них обычно выбирают её.

Как выбрасывать свои исключения

Исключения нужны не только для ошибок, которые обнаруживает сам язык. Когда твоя функция получает входные данные, с которыми не может работать, она может выбросить исключение, чтобы отказаться, а вызывающий код решит, что делать дальше. Небольшой собственный класс исключения даёт ошибке имя, которое её описывает.

70
Refused: cannot take 250, balance is 100

В Python для этого используется raise. В Java, C++ и JavaScript то же самое делает throw.

Обработка исключений в других языках

ЯзыкКлючевые словаЧто стоит знать
Pythontry, except, else, finally, raiseКаждое исключение это объект, унаследованный от BaseException
Javatry, catch, finally, throw, throwsПроверяемые исключения, например IOException, нужно перехватить или объявить через throws
C++try, catch, throwНет finally; ресурсы освобождают деструкторы при раскрутке стека
JavaScripttry, catch, finally, throwОшибки в async коде перехватывают через try вокруг await
CнетФункции возвращают код ошибки, и многие устанавливают errno
Goнет для обычных ошибокФункции возвращают значение error, которое проверяет вызывающий код

Тот же пример с разбором на Java выглядит так:

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 делит исключения на две группы. Проверяемые исключения, например IOException, описывают проблемы вне контроля программы, и компилятор отказывается собирать код, который их не перехватывает и не объявляет. Непроверяемые исключения, подклассы RuntimeException, например NullPointerException, обычно означают баг, и компилятор не заставляет их обрабатывать.

Частые ошибки

  • Перехват всего подряд. Голый except: в Python перехватывает и KeyboardInterrupt, поэтому Ctrl+C перестаёт работать, а except Exception: ловит баги, которые ты никогда не планировал. Перехватывай конкретный тип, который знаешь, как обработать.
  • Проглатывание ошибки. except ValueError: pass прячет проблему. Как минимум выведи или запиши в лог, что пошло не так.
  • Слишком большой блок try. Оборачивай только те строки, которые могут выбросить перехватываемое исключение, чтобы посторонняя ошибка не была обработана по случайности.
  • Перехват багов вместо исправления. IndexError из цикла, который делает на один шаг больше, это ошибка в коде. Её обработка сохраняет неправильный код в живых.
  • Ожидание, что catch предотвратит падение в C или C++. Ошибка сегментации это сигнал операционной системы, а не исключение, и в Linux и macOS catch (...) в C++ её никогда не увидит.

Что читать дальше

Ошибки, на которые реагирует обработка исключений, описаны на странице про ошибку времени выполнения, а падение, которое она перехватить не может, на странице про ошибку сегментации. Полный синтаксис есть в руководствах по исключениям в Python, try и catch в Java, исключениям в C++ и try и catch в JavaScript. В курсе Java и курсе Python они отрабатываются на настоящих упражнениях.

Часто задаваемые вопросы

Какие 5 ключевых слов используются для обработки исключений в Java?
try, catch, finally, throw и throws. try отмечает код, за которым нужно следить, catch обрабатывает конкретный тип исключения, а finally выполняет завершающий код независимо от того, было ли исключение. throw выбрасывает исключение, а throws в сигнатуре метода объявляет, какие проверяемые исключения метод может передать вызывающему коду.
Как устроена обработка исключений в C++?
В C++ используются try, catch и throw. Выбросить можно значение любого типа, но по соглашению выбрасывают объект, производный от std::exception, например std::runtime_error, и перехватывают его по ссылке: catch (const std::exception& e). В C++ нет finally; освобождение ресурсов происходит в деструкторах, которые вызываются автоматически при раскрутке стека.
Чем ошибка отличается от исключения?
В обычной речи ошибка это всё, что пошло не так, а исключение это объект, которым язык о ней сообщает. Java проводит границу чётче: Exception охватывает проблемы, которые программа может разумно обработать, а Error, например OutOfMemoryError или StackOverflowError, сигнализирует о сбое JVM, который программе обычно не стоит пытаться перехватывать. В Python ValueError и ZeroDivisionError оба исключения, несмотря на названия.
Чем throw отличается от throws в Java?
throw это инструкция, которая выбрасывает одно исключение в этом месте: throw new IllegalArgumentException("negative age");. throws это часть объявления метода, где перечислены проверяемые исключения, которые метод может передать вызывающему коду: void load() throws IOException. После этого компилятор заставляет каждый вызывающий код либо перехватить это исключение, либо тоже его объявить.
Замедляет ли обработка исключений код?
Вход в блок try в большинстве современных языков почти бесплатен. Начиная с Python 3.11, try практически ничего не стоит, если исключение не выброшено, а основные компиляторы C++ не добавляют затрат во время выполнения на пути, где ничего не выбрасывается. Выбросить и перехватить исключение намного медленнее, чем проверить if, поэтому в циклах, где важна скорость, проверяй частые случаи явно, а не полагайся на исключения.
Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ