Рубрики
Без рубрики

JavaScript Try-Catch Hid мои ошибки!

(Знамя фото Thomas Smith на Unsplash) позвольте мне начать с того, что я понял – JavaScript – отличный язык, а не винить. Я был полностью виноват – моя умственная модель обращения с ошибками была неполной, и это вызвало проблему. Следовательно, этот пост. Но сначала позвольте

Автор оригинала: FreeCodeCamp Community Member.

Позвольте мне начать с того, что я понял – JavaScript – отличный язык, а не винить. Я был полностью виноват – моя умственная модель обращения с ошибками была неполной, и это вызвало проблему. Следовательно, этот пост.

Но сначала позвольте мне дать вам какой-то контекст. Я писал кучу кода с участием сторонних API ( повторяющиеся счеты на стрипею и API на подписку и подписки , чтобы быть конкретным) и написал класс Wrapper и некоторые поперечные обработчики сервера, чтобы ответить на запросы от интерфейсной сети приложение. Все приложение реагирует + типографский + узел, с помощью KOA Server Отказ

Как часть этого я пытался справиться с следующими ошибками:

  1. Ошибки, брошенные по API полосой
  2. Ошибки, брошенные моим классом оболочки, особенно при выборе пользовательских данных из базы данных
  3. Ошибки в обработчиках маршрутов, которые возникают из комбинации вышеуказанного.

Во время разработки мои самые распространенные ошибки были неполными данными в запросах серверов и неправильные данные, переданные на полоску.

Чтобы помочь вам визуализировать поток данных, позвольте мне дать вам немного фона на стороне сервера. Как правило, это какова цепочка вызовов функций:

Обработчик маршрута -> Slipe Wrapper -> Plipe API

Первая функция, называемая функцией, будет в обработчике маршрута, затем в классе полосных обертков, внутри которого будет называться метод API полосы. Таким образом, стек вызовов имеет обработчик маршрута внизу (сначала называемая функциями) и методом API полосы на верхней части (последняя называемая функция).

Проблема заключалась в том, что я не понял, где поставить мою обработку ошибок. Если я не поставил обработчик ошибок в сервере, то узел будет сбоя (буквально, выйти за выполнение!), И передний конец будет принимать ошибку HTTP-ответ (как правило, HTTP 5xx ERR0R ). Поэтому я положил несколько попробовать Художественные обработчики внутри различных методов называются и добавлены операторы ведения журнала внутри поймать блокировать. Таким образом, я мог отладить ошибку, отслеживая журналы.

Пример вызовов логики:

 function stripeAPI(arg){
    console.log('this is the first function')
    if(!arg) throw new Error('no arg!')
    // else
    saveToDb()
}

function stripeWrapper(){
    console.log('this is the second function, about to call the first function')
    try{
        stripeAPI()
    } catch(err) {
//         console.log(' this error will not bubble up to the first function that triggered the function calls!')
    }
}

function routeHandler(){
    console.log('this is the third  function, about to call the second function')
    stripeWrapper()
}


function callAll(){
    try{
       routeHandler() 
       return 'done'
    } catch (err){
       console.log('error in callAll():', err)
       return ' not done '
    }
    
}


callAll()

Проблемы?

  1. Если я не регистрировал ошибку, я потерял Ошибка! В приведенном выше фрагменте обратите внимание, что, хотя я позвонил Сначала () Без необходимых аргументов ошибка определена в определении Первый не бросил! Кроме того, нет savetodb () Метод определен … И все же это не было поймано! Если вы запускаете этот код выше, вы увидите, что он возвращает «Готово» – и вы понятия не имеете, что ваша база данных не обновлена, и что-то пошло не так! ☠️☠️☠️.
  2. Моя консоль имела слишком много журналов, повторяя ту же ошибку. Это также означало, что в производстве было чрезмерное ведение журнала …?
  3. Код выглядел уродливым. Почти как уродливая как моя консоль.
  4. Другие, которые работали с кодом, обнаружили, что он запутал и отладки кошмара. ?

Ни один из них не являются хорошими результатами, и все избегают.

Концепции

Итак, давайте сделаем некоторые основы с пути. Я уверен, что вы знаете их, но некоторые люди не могут, и давайте не оставим их позади!

Некоторые основные терминологии:

Ошибка . – Также известен как «исключение», является когда что-то выходит не так в узлевом коде, и программа выходит сразу. Ошибки, если не обрабатываются, приведет к тому, что программа будет прийти к визжению, а уродливые сообщения извержены в консоль, с длинным и в целом отвратительным сообщением об ошибках.

Бросить бросить Оператор – это то, как язык обрабатывает ошибку. Используя бросить Вы генерируете исключение, используя значение, которое вы поставили после оператора. Обратите внимание, что код после бросить не выполняется – в этом смысле это как Возвращение утверждение.

Ошибка . – Есть JavaScript объект называется Ошибка . Отказ Ошибка получает «брошенное», чтобы помочь программисту знать, что что-то нужно обрабатывать. Подумайте об этом как о маленькой тикающей бомбе? которые бросаются из одной функции к другой внутри цепочки функционных вызовов. Технически, вы можете бросить любые данные, включая JavaScript примитивы как ошибку, но, как правило, хорошая идея бросить Ошибка . объект.

Вы обычно строите Ошибка . Объект, проходя в строке сообщения, как так: Новая ошибка («Это ошибка») Отказ Но просто создавая новый Ошибка . ? Объект бесполезно, так как это только половина работы. Вы дошли до бросить Это так может быть поймано. Вот как это становится полезным.

Языки, как правило, поставляются с Стандартный набор ошибок, Но вы можете создать пользовательское сообщение об ошибке с Новая ошибка («Это мое сообщение об ошибке») Конструктор, и ваше сообщение об ошибке должно помочь вам поработать, что происходит. Больше на Ошибки узла.

Поймать Это то, что вы делаете, когда кто-то бросает что-то у вас, верно? Вы, вероятно, сделаете это рефлексивно, даже если кто-то бросил вас одним из них …?!

поймать Заявление в JavaScript позволяет обрабатывать ошибку? Это бросается. Если вы не поймаете ошибку, то ошибка «пузыри вверх» (или вниз, в зависимости от того, как вы просматриваете стек вызова) до тех пор, пока он не достигнет первой под названием функцию, и там она будет сбиваться программа.

В моем примере моим ошибка, выброшенная на полосою API, позволит встать на свой путь к функции обрабатываемого маршрута, если только я не поймаю его где-то по пути и справился с ним. Если я не справимся с ошибкой, узел бросит uncuptexception Ошибка, а затем завершайте программу.

Вернемся к моему примеру:

Стек вызовов

Обработчик маршрута -> Slipe Wrapper -> Plipe API

Путь ошибок

Slipe API ( ? выбрасывает здесь) -> API обертка ( � � не поймал) -> Маршрут Обработчик ( � �still не поймал) -> Ccrrahhh ???

Мы хотим избегать сбоев приложений, поскольку он может привести к повреждению ваших данных, ваше состояние быть непоследовательным, и ваш пользователь, чтобы подумать, что ваше приложение отстой. Таким образом, обработка ошибок, вдумчиво требует много уровней анализа.

Есть некоторые подробные руководства по обращению об ошибках в JavaScript, а одно из моих любимых – здесь , но я приведу итоги своих ключевых наклон для вас здесь.

Try-catch

Используйте их для изящных ошибок, но будьте осторожны о где и Когда Отказ Когда ошибки пойманы и не обрабатываются правильно, они потеряны. Это процесс «пузыринга» происходит только до тех пор, пока ошибка не сталкивается с поймать утверждение. Если есть поймать Заявление в цепочке вызовов, которая перехватывает ошибку, ошибка не будет разорвать приложение, но не обрабатывать ошибку, будет скрывать его! Затем он проходит как аргумент для поймать И это требует от вас, чтобы справиться с этим там.

try{
// code logic
} catch (error) {
// handle the error appropriately
}

Так что очень важно поймать и Обращайтесь с ошибкой в точке, где она делает наиболее логичный смысл для вас, когда вы должны отладить его. Заманчиво думать, что вы должны поймать его в самом первом месте (последняя функция вызывала, которая сидит прямо на верхней части стека вызовов), но это не так!

Маршрут-Обработчик -> Уплотнитель на полоску (не поймай здесь!) -> API полоса

Если я поставил свой попробовать В полосой обертке, которая напрямую призывает API полос, то у меня нет информации о где Моя функция обертки нашивки была вызвана. Может быть, это был обработчик, может быть, это был еще один метод внутри моей обертки, может быть, это было в другом файле всего! В этом простом примере это, очевидно, называется обработчиком маршрута, но в приложении Real World его можно назвать в нескольких местах.

Вместо этого мне имеет смысл поставить попробовать В обработчике маршрута, который является самым первым местом, где начинаются вызовы функций, которые привели к ошибке. Таким образом, вы можете проследить стек вызовов (также называемым раскручиванием стека вызовов) и сверните в ошибку. Если я отправлю плохие данные на полоску, она бросит ошибку, и эта ошибка пройдет через мой код, пока не поймаю его.

Но когда я поймаю его, мне нужно обращаться с этим правильно, или я мог непреднамеренно скрыть эту ошибку. Обработка ошибок обычно означает решение, нужен ли мне мой передний пользователь, чтобы знать, что что-то пошло не так (например, их платеж не работал, например), или это просто внутренняя ошибка сервера (например, полоса не может найти идентификатор продукта I ID Прошло), что мне нужно изящно обрабатывать, не отключая моих передних конечных пользователей и разбиваем код узла. Если я добавил вещи в базу данных, которые не являются правильными, то я должен очистить эти ложные пишеты сейчас.

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

 function stripeAPI(arg){
    console.log('this is the first function')
    if(!arg) throw new Error('no arg!')
    // else
    saveToDb()
}

function stripeWrapper(){
    console.log('this is the second function, about to call the first function')
    try {
        stripeAPI()
    } catch(err) {
        console.log('Oops!  err will not bubble up to the first function that triggered the function calls!')
    }
}

function routeHandler(){
    console.log('this is the third  function, about to call the second function')
    stripeWrapper()
}


function callAll(){
    try {
       routeHandler() 
       return 'done'
    } catch (err){  
       console.log('error in callAll():', err)
       return ' not done '
    }
    
}


callAll()

… Как вы можете видеть выше, если я поймаю его и ловит его на среднем уровне (мой класс для обертки), он не достигнет Routehenler или Callall И мое приложение не узнает что-то пошло не так. Callall все еще возвращается сделано И единственным доказательством чего-то пошло не так, было в операторе журнала: «Упс! ERR не будет пузым до первой функции, которая вызвала вызовы функций! Отказ Если бы мы не ставили оператор журнала там, что ошибка исчезла без следа.

Это «скрытие ошибок», и она делает отладку боли. Если я добавлю попробовать Но ничего не делай в поймать Заявление, я помешаю мою программу разбивающейся. Но я также в конечном итоге «скрываю» проблему! Обычно он приводит к непоследовательному состоянию – части моего сервера считают, что все в порядке, и говорит мой передний конец. Но другая часть моего сервера указала, что что-то не так!

В этом простом примере их легко разгадать, но думать о глубоком вложенном, вызванном всем вашим приложением – какой кошмар!

Если вам абсолютно необходимо обрабатывать ошибку в середине стека вызовов, то обязательно перекатите ошибку соответствующим образом. Это означает, что закончится ваш поймать Заявление с другим Ошибка броска операция. Таким образом, ошибка будет выброшена снова и продолжать «пузыми» к первой функции (внизу стека вызовов), которая вызвала цепочку вызовов, где она может быть правильно обработана снова.

Вот что похоже, добавляя только один маленький перебрасывающий в stripewrapper () функция. Запустите код и увидим разницу в результате, потому что Callall () Теперь передается ошибка!

function stripeWrapper(){
    console.log('this is the second function, about to call the first function')
    try{
        stripeAPI()
    } catch(err) {
        console.log('Oops!  err will not bubble up to to first function that triggered the function calls!')

        throw err  // add this to re-throw!

    }
}

function callAll(){
    try{
       routeHandler() 
       return 'done'
    } catch (err){  // catches the re-thrown error and prints it to console!
       console.log('error in callAll():', err)
       return ' not done '
    }
    
}

Поскольку вы бросили ошибку на средней сцене, она пошла на внешнюю границу и там попала. Код возвращается не сделано И вы можете исследовать, почему ошибка говорит «нет arg». Вы также можете увидеть, что он никогда не выполняется savetodb () , поскольку ошибка бросила, прежде чем этот код может быть выполнен! Это может быть хорошо в тех случаях, когда вы экономите вещи в базу данных Предполагая, что не было никаких ошибок до этого момента Отказ Представьте себе сохранение вещей в базу данных, которые никогда не должны быть сохранены – это грязные данные в базе данных сейчас! ???

Итак, не делайте то, что я делал в моих первых днях программирования и просто зарегистрируйте ошибку в каждый Шаг в стеке вызов и переверните его. Это просто означает, что вы получите несколько журналов для каждой ошибки, так как проходит через стек вызовов! Перехватить только ошибку в месте, где вы можете наиболее эффективно и использовать его, в идеале один раз в данной цепочке вызовов.

В общем, это действительно помогает, если вы разместите свой Попробуйте поймать Заявление на внешней (первой вызывающей) функции, которая лежит в нижней части стека вызовов. Вы можете идентифицировать это как место, что ошибка будет пузыми до Незадолго до бросать uncuptexception ошибка. Это хорошее место, чтобы поймать, журнал и справиться с этим.

Чтобы увидеть разницу в обработке, когда вы не используете попробовать Просто модифицируйте Callall () выглядеть так:

function callAll(){
    routeHandler()  
    
    // this won't run!
    console.log('This function is not contained inside a try-catch, so will crash the node program.')
}

callAll()

Вы заметите, что console.log Заявление никогда не работает здесь, потому что программа вылетает, когда RouteHandler () заканчивается выполнением.

Эмпирические правила ???

Итак, давайте суммируем некоторые быстрые правила, которые будут охватывать 90 +% ваших потребностей:

  1. Не помешайте свой код с помощью попробовать заявления
  2. Попробуйте как можно больше к поймать только один раз в данной цепочке вызовов функций
  3. Попробуйте разместить это поймать На самой внешней границе – первая функция, которая запускает цепочку вызовов функций (внизу стека вызовов)
  4. Не оставляйте свой поймать Заявление пустое как способ остановить вашу программу от аварии! Если вы не обрабатываете его, шансы это приведет к непоследовательному состоянию между вашим передним и концом спины. Это может быть опасно и привести к ужасному пользователю?!
  5. Не используйте поймать Заявление только в середине стека вызовов, а не на внешней границе. Это заставит ошибку получить «скрытую» в середине вашего кода, где она не собирается правильно помочь вам отладки или управлять данными. Другие, которые работают с вашим кодом, найдут где вы живете и отрезаете интернет-соединение.
  6. Поймайте его там, где вам нужно знать, и где вы можете значимы, делать все, что нужно почистить вещи.

Slipe API ( ? выброшены здесь) -> Обелочка API ( ? Прохождение) -> Обработчик маршрута ( ? поймал, обрабатывался, вошли в систему) -> ???

Спасибо за чтение!

Если вы хотели бы узнать больше о моем путешествии в код, проверить Эпизод 53 из FreeCodecamp подкаст , где Quincy (основатель FreeCodeCamp) и я делюсь нашим опытом в качестве карьерных чейнджеров, которые могут помочь вам в вашем путешествии. Вы также можете получить доступ к подкасте на iTunes , Сказки и Spotify Отказ

Я также буду держать несколько AMAS и вебинаров в ближайшие месяцы. Если это интересно вам, пожалуйста, дайте мне знать, собираясь здесь Отказ И, конечно, вы также можете твитнуть меня на @Zubinpratap Отказ