try…catch — JavaScript — Дока
Кратко
Скопировано
Конструкция try
позволяет выполнить произвольный код, но если в нем произошла ошибка, то программа не остановит своё выполнение, а перейдёт в блок catch
, где ошибку можно обработать.
Как понять
Скопировано
Ошибки в программах это очень неприятно, но никто не застрахован от их появления. К тому же, ошибки могут появляться в тех ситуациях, которые не зависят от нас самих. Например, пользователь неправильно воспользовался программой. Поэтому в языке необходимы конструкции, которые позволяют выполнить произвольный код, но в случае ошибки дать возможность её обработать.
В JavaScript ситуация ещё сложнее. Если во время работы скрипта возникла ошибка и она не была обработана, то выполнение останавливается, и программа больше не работает.
Конструкция try
делает программы стабильнее — в случае ошибки мы можем продолжить выполнение. Мы можем написать любой синтаксически верный код и, если он выполнится без ошибок, то отлично. Если же что-то пойдёт не так, то выполнится код, написанный в catch
.
Представьте, что вы тренируетесь отбивать мяч в бейсбол. У вас есть партнёр, который будет ловить мяч, в случае вашей ошибки, если отбить мяч не удастся. В большинстве попыток у вас все будет получаться хорошо, но если же случится промах, то второй игрок поймает мяч и вернёт его на место, чтобы можно было попробовать снова.
С пойманной в catch
ошибкой можно поступить как угодно: отправить данные в специальный логгер, обработать данные из неё и даже выбросить новую ошибку, которая может быть поймана в другом месте и т.д.
Как пишется
Скопировано
Базовый случай
Скопировано
Чтобы использовать try
, необходимо в блоке try
написать код, который нужно исполнить, а в блоке catch
написать, что делать в случае ошибки.
try { someFunction() anotherFunction()} catch (err) { console.log('Поймали ошибку! Вот она: ', err.message)}
try {
someFunction()
anotherFunction()
} catch (err) {
console.log('Поймали ошибку! Вот она: ', err.message)
}
Если в блоке try
не произошло ошибок, то код в блоке catch
не выполнится.
Важно помнить, что код в try
должен быть синтаксически верным. Если написать невалидный код (например, не закрыть фигурные скобки), то скрипт не запустится, потому что JavaScript не поймёт код. Ошибки, которые обработает блок
, будут ошибками во время выполнения программы.
В случае ошибки выполнение в блоке try
прерывается и сразу же переходит в блок catch
. После него скрипт продолжит своё выполнение, как и прежде.
try { const six = 6 // 1. Создаём константу console.log(six) // 2. Выведет 6 six = 7 // Ошибка! Присваиваем новое значение в const // с этого места управление переходит в catch const nine = 9 // не выполнится console.log(six + nine) // и это тоже не исполнится} catch (err) { console.log('Поймали ошибку!') // 3. Обработали ошибку}console.log('Что ж, можно и продолжать') // 4. Будет выполняться дальше
try {
const six = 6 // 1. Создаём константу
console.log(six) // 2. Выведет 6
six = 7 // Ошибка! Присваиваем новое значение в const
// с этого места управление переходит в catch
const nine = 9 // не выполнится
console.log(six + nine) // и это тоже не исполнится
} catch (err) {
console.log('Поймали ошибку!') // 3. Обработали ошибку
}
console.log('Что ж, можно и продолжать') // 4. Будет выполняться дальше
finally
Скопировано
Рассмотрим ситуацию, когда в случае успеха или неудачи выполнения какого-то участка кода нам необходимо проводить какие-то действия, чтобы корректно завершить работу скрипта.
try { // подключаемся к вебсокету, но в конце нужно обязательно отключиться webSocket.connect('ws://....') callMayThrowError()} catch (err) { ...}// Пробуем отключаться после try...catchwebSocket.disconnect('ws://....')
try {
// подключаемся к вебсокету, но в конце нужно обязательно отключиться
webSocket.connect('ws://....')
callMayThrowError()
} catch (err) {
...
}
// Пробуем отключаться после try...catch
webSocket.disconnect('ws://....')
Казалось бы никаких проблем с этим кодом быть не должно, ведь неважно выполнится код в блоке
правильно или попадёт в catch
, следующая строчка должна выполниться. Однако возможна ситуация, что в блоке catch
тоже возникнет ошибка, и тогда выполнение следующей строчки уже не случится.
function doSomeWithError(e) { throw new Error('new error')}try { // подключаемся к вебсокету, но в конце нужно обязательно отключиться webSocket.connect('ws://....') callMayThrowError()} catch (err) { // Здесь тоже может возникнуть ошибка doSomeWithError(err)}// В случае ошибки эта строчка уже не выполнитсяwebSocket.disconnect('ws://....') function doSomeWithError(e) { throw new Error('new error') } try { // подключаемся к вебсокету, но в конце нужно обязательно отключиться webSocket.connect('ws://....') callMayThrowError() } catch (err) { // Здесь тоже может возникнуть ошибка doSomeWithError(err) } // В случае ошибки эта строчка уже не выполнится webSocket.disconnect('ws://....')
Как же тогда гарантированно освободить ресурсы при любом исходе выполнения?
В конструкцию try
можно добавить блок finally
, который выполнится после блоков try
и catch
. Неважно какой код выполнился в предыдущих блоках, после их завершения (даже если из
была выброшена новая ошибка) исполнится код в блоке finally
.
try { webSocket.connect('ws://....') callMayThrowError()} catch (err) { // Здесь тоже может возникнуть ошибка doSomeWithError(err)} finally { // Выполнится всегда webSocket. disconnect('ws://....')}
try {
webSocket.connect('ws://....')
callMayThrowError()
} catch (err) {
// Здесь тоже может возникнуть ошибка
doSomeWithError(err)
} finally {
// Выполнится всегда
webSocket.disconnect('ws://....')
}
Наличие блока finally
необязательно.
можно использовать и без блока catch
.
try { // Отправить данные на сервер, здесь нам неважна обработка ошибки sendData()} finally { // Закрыть соединение при любом результате closeConnection()}
try {
// Отправить данные на сервер, здесь нам неважна обработка ошибки
sendData()
} finally {
// Закрыть соединение при любом результате
closeConnection()
}
Ошибки в catch
Скопировано
Может возникнуть ситуация, когда скрипт обработки ошибки тоже может сломаться. При этом могут возникнуть случаи, когда мы хотим намеренно выбросить новую ошибку из catch
, или пробросить текущую, чтобы её обработать в другом месте.
Хорошей практикой считается обрабатывать в модуле только те ошибки, которые связаны непосредственно с ним, а все остальные пробрасывать дальше.
// parse-module.js// Есть свой тип ошибкиclass ParsingError extends Error { ...}function parse(data) { try { parseData(data) } catch (err) { if (err.name !== 'ParsingError') { // Другой тип ошибок пробрасываем дальше throw err } logError(err)}}// parse-module.js // Есть свой тип ошибки class ParsingError extends Error { ... } function parse(data) { try { parseData(data) } catch (err) { if (err.name !== 'ParsingError') { // Другой тип ошибок пробрасываем дальше throw err } logError(err) } }
Таким образом, можно разделить ответственность, а обработкой проброшенной ошибки займётся внешний catch.
import parse from 'parse-module'try { parse(data)} catch (e) { console.log('Неизвестная ошибка парсинга:', e)}
import parse from 'parse-module'
try {
parse(data)
} catch (e) {
console. log('Неизвестная ошибка парсинга:', e)
}
Ошибки в асинхронном коде
Конструкция try
работает только синхронно. Таким образом, с помощью try
нельзя обработать ошибку, которая возникла в асинхронном коде.
try { // Код выполнится корректно, т.к. отсюда вернулся промис Promise.reject('err')} catch (e) { // Ошибка не будет поймана console.log('Ошибка', e)}try { // Здесь также код выполнится корректно, потому что установил таймаут без ошибок setTimeout(() => { throw Error('ошибка') }, 1000)} catch (e) { // Ошибка из таймаута также сюда не попадёт console.log('Ошибка', e)}
try {
// Код выполнится корректно, т.к. отсюда вернулся промис
Promise.reject('err')
} catch (e) {
// Ошибка не будет поймана
console. log('Ошибка', e)
}
try {
// Здесь также код выполнится корректно, потому что установил таймаут без ошибок
setTimeout(() => {
throw Error('ошибка')
}, 1000)
} catch (e) {
// Ошибка из таймаута также сюда не попадёт
console.log('Ошибка', e)
}
Однако, если записать асинхронный код в синхронном стиле с помощью async/await, то в этом случае обработку ошибок можно осуществлять с помощью try
.
async function handlePromise() { try { // Промис вернется с ошибкой await Promise.reject('err') } catch (e) { // Теперь ошибка будет поймана console.log('Ошибка', e) // err }}handlePromise()
async function handlePromise() {
try {
// Промис вернется с ошибкой
await Promise.reject('err')
} catch (e) {
// Теперь ошибка будет поймана
console.log('Ошибка', e) // err
}
}
handlePromise()
Чтобы поймать ошибку из set
, блоки try
должны находиться внутри функции.
На практике
Скопировано
Егор Огарков советует
Скопировано
Любой асинхронный код можно переписать в синхронном стиле через async
, чтобы использовать единый стиль обработки ошибок, используя try
. Например, перепишем установку таймаута из примера выше:
function wait(ms) { return new Promise((resolve) => setTimeout(resolve, ms))}async function timeout(fn, ms) { try { // Ждем таймаут await wait(ms) // И выполняем функцию fn() } catch (err) { // Ловим ошибку console.log('Ошибка', err) }}
function wait(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
async function timeout(fn, ms) {
try {
// Ждем таймаут
await wait(ms)
// И выполняем функцию
fn()
} catch (err) {
// Ловим ошибку
console. log('Ошибка', err)
}
}
Теперь можно вызывать функцию как прежде, ошибка будет поймана.
timeout(() => { throw Error('ошибка')}, 1000)
timeout(() => {
throw Error('ошибка')
}, 1000)
Обработка ошибок JavaScript с помощью Try Catch
JavaScript Try Catch: что вам нужно знать
Изображение с сайта unsplash.comВы когда-нибудь делали ошибку в своем коде, которую потом нельзя было выполнить? Или вы отправили запрос на сервер, который дал сбой и привел к неожиданным последствиям? Конечно, у вас есть — как и у многих из нас.
Такие ошибки имеют загадочные имена и называются исключениями . Вы можете задаться вопросом, как лучше с ними справиться. Каждый язык программирования дает нам некоторые инструменты для этого, и JavaScript не исключение.
Чтобы устранить эти ошибки в JavaScript, мы узнаем, как использовать try/catch
.
В целом, блок try/catch
в JavaScript выглядит следующим образом:
Блок try
содержит набор операторов, в которых может возникнуть исключение, и за ним всегда следует блок catch, который обрабатывает исключение, которое происходит в связанном блоке try. Блок catch
«отлавливает» ошибку, чтобы вы могли получить больше информации о ней, проверив свойства объекта ошибки.
В дополнение к конструкции try/catch в этом контексте также широко используется ключевое слово throw
. Применяя его, , мы можем создавать собственные настраиваемые исключения . Это делает наше приложение и бизнес-логику более мощными, понятными и, я бы сказал, удобочитаемыми.
Первый реальный пример, который пришел мне в голову, — это проверка данных:
Во фрагменте кода мы пытаемся получить токен из свойства запроса запроса. Если токена нет или значение пустое, мы буквально «кидаем» ошибку, которую ловит поймать блок
и показать в логах. Наше исследование не останавливается на достигнутом.
Поскольку Error
— это класс, очевидно, что для ясности можно создать собственные классы ошибок.
Проверьте это:
В этом примере мы создали собственный класс ValidationError
и использовали его для обработки ошибок конкретной бизнес-логики выше. В логах пишет "Не удалось аутентифицировать ValidationError. Не получили [токен]»
. Применяя этот метод, вы можете определить тип ошибки и по-разному ее обработать:
Последний метод, о котором я здесь упомяну, — повторное генерирование ошибки. Используйте его, когда вам нужно обработать ошибку на верхнем этапе, а не внутри конкретного обработчика.
Существует стандарт де-факто, согласно которому обработчик ошибок (или конкретный блок catch) должен обрабатывать конкретно связанную с ним ошибку, а все остальное следует перебрасывать дальше. В итоге должен быть обработчик ошибок по умолчанию, который обрабатывает все, что не было перехвачено нашими гейткиперами (блоки перехвата):
Теперь давайте немного рефакторим наш код. Код проверки лучше вынести в отдельную функцию для удобочитаемости:
Иногда может потребоваться в случаях try/catch
и Success/Fail, чтобы было какое-то завершающее и независимое действие. Основной вариант использования следующий: код открывает файловый дескриптор; читает/обрабатывает данные внутри него; и, в случае ошибки или успешного завершения, файл должен быть закрыт, а ресурсы освобождены.
Для этого можно использовать try/catch/finally
конструкция в JavaScript:
Обратите внимание, что весь вышеупомянутый код является синхронным. В современном JavaScript (ES2017 и новее) try/catch/finally
можно полностью использовать с асинхронными функциями. Подробнее см. в этом руководстве.
Предположим, что функция аутентификации является асинхронной:
Итак, если обещание отклонено, блок catch обработает его так же, как описано выше.
Еще один совет: старайтесь избегать вложенных блоков try/catch . Если вы включаете их, ваш код, вероятно, нарушает SRP. В качестве быстрого исправления вы можете попробовать переместить один из блоков в отдельную функцию.
Спасибо за внимание!
Первоначально опубликовано по адресу: https://anywhere.epam.com/en/blog/javascript-try-catch-all-you-need-to-know
Не создавайте веб-монолиты. Используйте Bit для создания и компоновки несвязанных программных компонентов — в ваших любимых средах, таких как React или Node. Создавайте масштабируемые и модульные приложения с мощными и приятными возможностями разработки.
Перенесите свою команду в Bit Cloud, чтобы совместно размещать компоненты и совместно работать над ними, а также значительно ускорить, масштабировать и стандартизировать разработку в команде. Начните с компонуемых интерфейсов, таких как Design System или Micro Frontends, или исследуйте компонуемый сервер. Попробуйте →
Узнать больше
Как мы создаем микроинтерфейсы
Создание микроинтерфейсов для ускорения и масштабирования процесса веб-разработки.
blog.bitsrc.io
Как мы создаем систему проектирования компонентов
Создание системы дизайна с компонентами для стандартизации и масштабирования нашего процесса разработки пользовательского интерфейса.
blog.bitsrc.io
Компонуемое предприятие: руководство
Чтобы работать в 2022 году, современное предприятие должно стать компонуемым.
blog.bitsrc.io
7 инструментов для ускоренной разработки интерфейса в 2022 году
Инструменты, которые необходимо знать, чтобы создавать современные приложения интерфейса быстрее и получать больше удовольствия.
blog.bitsrc.io
Как использовать операторы try-catch в JavaScript
Educative Answers Team
Grokking the Behavioral Interview
Многих кандидатов отклоняют или понижают на технических собеседованиях из-за плохой успеваемости в поведенческих или культурных интервью. Пройдите собеседование с помощью этого бесплатного курса, где вы будете практиковаться, уверенно отвечая на поведенческие вопросы интервью.
Обработка исключений — это действие, обеспечивающее обработку кода, выдающего ошибку или прерывающего выполнение программы, без выдачи ошибки.
Как
try/catch
помогает в обработке исключений? Роль try/catch
следующая:
try
: Блок кода, следующий за этим оператором, будет содержать код, который нужно попробовать и посмотреть, не выдает ли он ошибкуcatch
: Блок, следующий за этим оператором, увидит, не дал ли код, следующий за операторомtry
, ошибку, и решит, что с этим делать
С помощью этих операторов в JavaScript вы также можете добавить предложение throw
или finally
. Посмотрим, какую роль они играют.
Фрагмент кода может по какой-либо причине привести к ошибке, поэтому мы используем методы для обработки этих ошибок, чтобы программа показала нам, в чем именно заключается ошибка, и мы могли решить, что делать с ошибкой, избегая программы. крушение.
Синтаксис
Теперь, когда мы знаем, что делает каждый оператор и почему он используется, давайте посмотрим на синтаксис ниже:
try{
// Здесь находится код для проверки на наличие ошибок
throw // Здесь можно создать собственную ошибку
}
catch(error){
// Здесь находится код для обработки ошибок
}
finally{
//Здесь написан код, который будет выполняться в конце всех инструкций
}
Примеры:
Давайте рассмотрим несколько простых примеров того, как выполнить обработку исключений в JavaScript
1 , Используя простой
try/catch
оператор В приведенном ниже примере в части кода try
мы просто вызываем функцию addAlert()
, которая не была определена. Учитывая, что это выдаст ошибку, логируем ошибку в консоль в блоке catch
.
try{
addAlert()
}
catch(ошибка){
console.log(ошибка)
console.log("Конец блока try-catch")
9 0
} } , Использованиеtry/throw/catch
операторовВ приведенном ниже примере показано, как мы можем создать собственную ошибку в блоке
throw
. Затемпопробуйте
код, который долженвыдать
ошибку, которая должна быть обнаружена блокомcatch
.try{
throw new Error ("Это новая ошибка")
}
catch(ошибка){
console.log(ошибка)
console.log("Конец блока try-catch ")
}
3. Использование
try/catch/throw/finally
вместеЭтот последний пример покажет, как также использовать оператор
finally
с тремя другими операторами. В этом примере мы не показываем всю ошибку, а в блокеcatch
мы только что зарегистрировали, что ошибка была обработана.