try...catch
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Конструкцияtry...catch
пытается выполнить инструкции в блокеtry
, и, в случае ошибки, выполняет блокcatch
.
Синтаксис
try { try_statements}[catch (exception_var_1 if condition_1) { // не стандартно catch_statements_1}]...[catch (exception_var_2) { catch_statements_2}][finally { finally_statements}]
try_statements
Инструкции для выполнения.
catch_statements_1
,catch_statements_2
Инструкции, которые будут выполнены, если произойдёт ошибка в блоке
try
.exception_var_1
,exception_var_2
Идентификатор для хранения объекта ошибки, который впоследствии используется в блоке
catch
condition_1
Условное выражение.
finally_statements
Инструкции, которые выполняются после завершения блока
try
. Выполнение происходит в независимости от того, произошла ошибка или нет.
Описание
Конструкцияtry
содержит блокtry
, в котором находится одна или несколько инструкций (Блок ({}
) обязательно должен присутствовать, даже если выполняется всего одна инструкция), и хотя бы один блокcatch
илиfinally
. Таким образом, есть три основные формы конструкцииtry
:
try {...} catch {...}
try {...} finally {...}
try {...} catch {...} finally {...}
Блокcatch
содержит инструкции, которые будут выполнены, если в блокеtry
произошла ошибка. Если любая инструкция в блокеtry
выбрасывает исключение, то управление сразу же переходит в блокcatch
. Если в блокtry
не было выброшено исключение, то блокcatch
не выполняется.
Блокfinally
выполнится после выполнения блоковtry
иcatch
, но перед инструкциями, следующими за конструкциейtry...catch
. Он выполняется всегда, в независимости от того, было исключение или нет.
Вы можете использовать вложенные конструкцииtry
. Если внутренняя конструкцияtry
не имеет блокаcatch
(такое может быть при её использовании в видеtry {...} finaly {...}
, потому чтоtry {...}
не может быть без блоков catch илиfinally
), будет вызвансatch
внешней конструкцииtry
.
Конструкцияtry
также используется для обработки исключений JavaScript (то есть, выброшенных внутренними функциями языка или парсером). Загляните вJavaScript руководство для дополнительной информации о JavaScript исключениях.
Безусловный блок catch
При использовании блокаcatch
, он вызывается для любого исключения в блокеtry
. Например, когда в следующем коде происходит ошибка, управление переходит к блокуcatch
.
try { throw "myException"; // создание исключения} catch (e) { // инструкции для обработки ошибок logMyErrors(e); // передать объект исключения обработчику ошибок}
Блокcatch
задаёт идентификатор (e
в примере выше) который содержит объект исключения (в примере выше — значение, переданное операторуthrow
). Область видимости этого объекта ограничивается блокомcatch
.
Условный блокcatch
"Условные блокиcatch
" можно создавать, используяtry...catch
сif...else if...else
, как здесь:
try { myroutine(); // может выбрасывать три вида исключений} catch (e) { if (e instanceof TypeError) { // обработка исключения TypeError } else if (e instanceof RangeError) { // обработка исключения RangeError } else if (e instanceof EvalError) { // обработка исключения EvalError } else { // обработка остальных исключений logMyErrors(e); // передать обработчику ошибок }}
Частый сценарий использования — обработать известные исключения, а при неизвестных ошибках, пробросить их дальше:
try { myRoutine();} catch (e) { if (e instanceof RangeError) { // обработка известного исключения, с которым // понятно, что делать } else { throw e; // пробросить неизвестные ошибки }}
Идентификатор исключения
Когда в блокеtry
выбрасывается исключение,exception_var
(т. е.e
в конструкцииcatch (e)
) содержит значение исключения. Его можно использовать, чтобы получить больше информации об выброшенном исключении. Идентификатор доступен только вобласти видимости блокаcatch
.
try { if (!firstValidation()) { throw 1; } if (!secondValidation()) { throw 2; }} catch (e) { // Выводит 1 или 2 (если не произошло никаких других ошибок) console.log(e);}
Блок finally
Блокfinally
содержит код который будет запущен после кода в блокахtry
иcatch
. Обратите внимание, что код в блокеfinally
запускается в независимости от того, было ли выброшено исключение или нет. Также код в блокеfinally
будет запущен вне зависимости от того, присутствует блокcatch
или нет. Блокfinally
можно использовать для того, чтобы скрипт безопасно завершил работу в случае ошибки. Например, если необходимо освободить память и ресурсы которые использовал скрипт.
Наличие специального блока, связанного с ошибкой, который выполняется вне зависимости от наличия исключительной ситуации, может показаться странным, но эта конструкция на самом деле весьма полезна. Рассмотрим пример кода:
function expensiveCalculations() { // Сложные вычисления}function maybeThrowError() { // Функция, которая может выбросить исключение if (Math.random() > 0.5) throw new Error();}try { // Теперь при прокрутке страницы будут происходить // сложные вычисления, что сильно скажется на // производительности window.addEventListener("scroll", expensiveCalculations); maybeThrowError();} catch { // Если функция maybeThrowError выбросит исключения, // управление сразу перейдёт в блок catch и // сложные вычисления продолжат выполняться до // перезагрузки страницы maybeThrowError();}window.removeEventListener("scroll", expensiveCalculations);
В этом примере, если функцияmaybeThrowError
выбросит исключение внутри блокаtry
, управление перейдёт в блокcatch
. Если и в блокеcatch
эта функция тоже выбросит исключение, то выполнение кода прервётся, и обработчик события не будет снят, пока пользователь не перезагрузит страницу, что плохо скажется на скорости работы. Для того, чтобы избежать таких ситуаций, следует использовать блокfinally
:
try { window.addEventListener("scroll", expensiveCalculations); maybeThrowError();} catch { maybeThrowError();} finally { window.removeEventListener("scroll", expensiveCalculations);}
Другой пример: работа с файлами. В следующем фрагменте кода показывается, как скрипт открывает файл и записывает в него какие-то данные (в серверном окружении JavaScript имеет доступ к файловой системе). Во время записи может произойти ошибка. Но после открытия файл очень важно закрыть, потому что незакрытый файл может привести к утечкам памяти. В таких случаях используется блокfinally
:
openMyFile();try { // Сделать что-то с файлом writeMyFile(theData);} finally { closeMyFile(); // Закрыть файл, что бы ни произошло}
Примеры
Вложенные блоки try
Для начала давайте посмотрим что делает этот код:
try { try { throw new Error("упс"); } finally { console.log("finally"); }} catch (e) { console.error("внешний блок catch", e.message);}// Вывод:// "finally"// "внешний блок catch" "упс"
Теперь отловим исключение во внутреннем блокеtry
, добавив к нему блокcatch
:
try { try { throw new Error("упс"); } catch (e) { console.error("внутренний блок catch", e.message); } finally { console.log("finally"); }} catch (e) { console.error("внешний блок catch", e.message);}// Output:// "внутренний блок catch" "упс"// "finally"
Наконец, пробросим ошибку
try { try { throw new Error("упс"); } catch (e) { console.error("внутренний блок catch", e.message); throw e; } finally { console.log("finally"); }} catch (e) { console.error("внешний блок catch", e.message);}// Вывод:// "внутренний блок catch" "oops"// "finally"// "внешний блок catch" "oops"
Любое исключение будет передано только в ближайший блокcatch
, если он не пробросит его дальше. Все исключения, выброшенными внутренними блоками (потому что код в блокеcatch
также может выбросить исключение), будут пойманы внешними.
Возвращение значения из блока finally
Если блокfinally
возвращает какое-либо значение, оно становится значением, которое возвращает вся конструкцияtry...catch...finally
, вне зависимости от любых инструкцийreturn
в блокахtry
иcatch
. Также игнорируются исключения, выброшенные блокомcatch
.
(() => { try { try { throw new Error("oops"); } catch (ex) { console.error("inner", ex.message); throw ex; } finally { console.log("finally"); return; } } catch (ex) { console.error("outer", ex.message); }})();// Logs:// "inner" "oops"// "finally"
"упс" не доходит до внешнего блока из-за инструкцииreturn
в блокеfinally
. То же самое произойдёт с любым значением, возвращаемым из блокаcatch
.
Спецификации
Specification |
---|
ECMAScript® 2026 Language Specification # sec-try-statement |