try. catch
Конструкция 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 .
Идентификатор для хранения объекта ошибки, который впоследствии используется в блоке catch
Инструкции, которые выполняются после завершения блока try . Выполнение происходит в независимости от того, произошла ошибка или нет.
Описание
Конструкция try содержит блок try , в котором находится одна или несколько инструкций (Блок ( <> ) обязательно должен присутствовать, даже если выполняется всего одна инструкция), и хотя бы один блок catch или finally . Таким образом, есть три основные формы конструкции try :
Блок 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; // пробросить неизвестные ошибки > >
Примечание: Firefox раньше поддерживал краткую запись условных блоков catch :
try < myroutine(); // может выбрасывать три вида исключения >catch (e if e instanceof TypeError) < // обработка исключений TypeError >catch (e if e instanceof RangeError) < // обработка исключений RangeError >catch (e if e instanceof EvalError) < // обработка исключений EvalError >catch (e) < // обработка остальных исключения logMyErrors(e); >
Однако, такой синтаксис никогда не был частью спецификации ECMAScript и был удалён из Firefox после версии 59. Сейчас он не поддерживается ни в одном браузере.
Идентификатор исключения
Когда в блоке 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 .
Спецификации
Совместимость
BCD tables only load in the browser
Смотрите также
Found a content problem with this page?
This page was last modified on 22 февр. 2023 г. by MDN contributors.
Your blueprint for a better internet.