Содержание

try…catch — JavaScript — Дока

Кратко

Скопировано

Конструкция try...catch позволяет выполнить произвольный код, но если в нем произошла ошибка, то программа не остановит своё выполнение, а перейдёт в блок catch, где ошибку можно обработать.

Как понять

Скопировано

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

В JavaScript ситуация ещё сложнее. Если во время работы скрипта возникла ошибка и она не была обработана, то выполнение останавливается, и программа больше не работает.

Конструкция try...catch делает программы стабильнее — в случае ошибки мы можем продолжить выполнение. Мы можем написать любой синтаксически верный код и, если он выполнится без ошибок, то отлично. Если же что-то пойдёт не так, то выполнится код, написанный в catch.

Представьте, что вы тренируетесь отбивать мяч в бейсбол. У вас есть партнёр, который будет ловить мяч, в случае вашей ошибки, если отбить мяч не удастся. В большинстве попыток у вас все будет получаться хорошо, но если же случится промах, то второй игрок поймает мяч и вернёт его на место, чтобы можно было попробовать снова.

С пойманной в catch ошибкой можно поступить как угодно: отправить данные в специальный логгер, обработать данные из неё и даже выбросить новую ошибку, которая может быть поймана в другом месте и т.д.

Как пишется

Скопировано

Базовый случай

Скопировано

Чтобы использовать try. ..catch, необходимо в блоке try написать код, который нужно исполнить, а в блоке catch написать, что делать в случае ошибки.

try {  someFunction()  anotherFunction()} catch (err) {  console.log('Поймали ошибку! Вот она: ', err.message)}
          try {
  someFunction()
  anotherFunction()
} catch (err) {
  console.log('Поймали ошибку! Вот она: ', err.message)
}

Если в блоке try не произошло ошибок, то код в блоке catch не выполнится.

Важно помнить, что код в try должен быть синтаксически верным. Если написать невалидный код (например, не закрыть фигурные скобки), то скрипт не запустится, потому что JavaScript не поймёт код. Ошибки, которые обработает блок

catch, будут ошибками во время выполнения программы.

В случае ошибки выполнение в блоке 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://....')

Казалось бы никаких проблем с этим кодом быть не должно, ведь неважно выполнится код в блоке

try правильно или попадёт в 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...catch можно добавить блок finally, который выполнится после блоков try и catch. Неважно какой код выполнился в предыдущих блоках, после их завершения (даже если из

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 необязательно.

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...catch работает только синхронно. Таким образом, с помощью try...catch нельзя обработать ошибку, которая возникла в асинхронном коде.

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...catch.

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()

Чтобы поймать ошибку из setTimeout(), блоки try.

..catch должны находиться внутри функции.

На практике

Скопировано

Егор Огарков советует

Скопировано

Любой асинхронный код можно переписать в синхронном стиле через async/await, чтобы использовать единый стиль обработки ошибок, используя try...catch. Например, перепишем установку таймаута из примера выше:

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 мы только что зарегистрировали, что ошибка была обработана.