Как правильно обрабатывать ошибки во фронтенд-приложениях

Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Код ошибки (англ. ) в программировании, — это номер (или сочетания буквы и номера), который соответствует конкретной проблеме в работе программы. Коды ошибок используются для идентификации неправильной работы аппаратного и программного обеспечения, неверного ввода данных пользователем без обработки возникающей при этом исключительной ситуации в коде программы, хотя иногда коды ошибок используются в сочетании с обработкой исключений. Коды ошибок не следует путать с кодами возврата, хотя они часто используются вместе при обработке ошибок. Одни из самых серьёзных кодов ошибок, которые могут встретить пользователи — это коды «Синего экрана смерти» операционной системы Microsoft Windows.

До стуктур еще не дорос, первые дни только изучаю С++.
Чтобы если возвращать код ошибки, то после вызова функции, придется еще добавлять какой-то обработчик ошибок, при большом количестве вызовов в разных местах, всюду придется совать обработчик. Если обработчик поместить в отдельную функцию, то опять же придется иметь по 1 функции с обработчиком на каждую уникальную функцию.
Поразмыслив и поковыряв самоучитель я пришел к выводу что хоть и кривой, но всё же реализацией того что я хочу сделать будет примерно следующее:

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

Код возврата (англ. ) программы, — это целочисленное значение, которое дочерний процесс возвращает родительскому процессу в момент завершения.

При выполнении компьютерных программ операционная система создаёт сущность, называемую процессом, с помощью которой она отслеживает и ведёт учёт выполнения программы. В многозадачных операционных системах, таких как Unix или Linux, новый процесс может быть порождён существующим процессом. Процесс-создатель называется «родительским», а создаваемый процесс — «дочерним». После создания дочерний процесс выполняется параллельно с родительским. Такая техника порождения дочерних процессов используется, чтобы передать часть работы дочернему процессу, в ситуациях, когда родительскому процессу не обязательно тратить на неё время. Когда дочерний процесс завершает своё выполнение, он автоматически либо явно по указанию программиста совершает системный вызов exit, передавая ему целое число. В результате вызова exit целое число передаётся родительскому процессу, который может получить его с помощью системного вызова wait.

Код состояния HTTP (англ. HTTP status code) — часть первой строки ответа сервера при запросах по протоколу HTTP.
Он представляет собой целое трёхразрядное десятичное число. Первая цифра указывает на класс состояния. За кодом ответа обычно следует отделённая пробелом поясняющая фраза на английском языке, которая разъясняет человеку причину именно такого ответа. Примеры:

  • 201 Created.
  • 401 Unauthorized.
  • 507 Insufficient Storage.

Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода. В настоящее время выделено пять классов кодов состояния.

Веб-сервер Internet Information Services в своих файлах журналов, кроме стандартных кодов состояния, использует подкоды, записывая их через точку после основного. При этом в ответах от сервера данный подкод не размещается — он нужен администратору сервера, чтобы тот мог более точно определять источники проблем.

5488 / 4258 / 1211Регистрация: 12.10.2013Сообщений: 12,254Записей в блоге: 2

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

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

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

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

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

Это ошибки, которые обычно говорят о багах в приложении, например, о необработанных исключениях.

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

Примечание — тема обработки ошибок во фронтенд-приложениях подробно рассматривается в рамках профессии «Фронтенд-программист». Базовые курсы в этой профессии, включая «Введение в программирование», «Основы командной строки», «Настройка окружения», «Системы контроля версий», доступны бесплатно после регистрации.

Провел небольшой тест.

По итогам +Errorlevel:

errorlevel = 0, даже, если пользователь ответил “Не заменять файл”.

errorlevel = 0, даже если пользователь ответил “Не заменять файл”
Чтобы консоль задала этот вопрос:
1) для одиночного файла нужно указать ключ /-y

2) для маски файлов работает по-умолчанию. Обратная операция – “принудительная замена”: ключ /y

Сравнение copy с verify off
1) без ключа
2) с ключем /v
показало, что в большинстве случаев с верификацией для копирования файла в ~250 МБ затрачивается на ~1,5 сек. больше времени. Не знаю, что именно оно проверяет, но уж файл точно целиком не считывается.

Самый простой и очень эффективный способ сообщить пользователю об ошибке — правильно использовать коды ответов HTTP. Коды статуса HTTP могут самостоятельно дать пользователю достаточно информации о том, почему возникла ошибка запроса, а также подсказать, что делать дальше.

Читайте также:  СЕРЬЕЗНОСТЬ КОД ОПИСАНИЕ ПРОЕКТ ФАЙЛ СТРОКА СОСТОЯНИЕ ПОДАВЛЕНИЯ ОШИБКА LNK 2019

«Ошибочные» коды ответов HTTP объединяются в две группы: ответы 4XX и ответы 5XX. Первые говорят о проблеме с запросом (клиентские ошибки), а вторые — о проблеме с сервером (серверные ошибки). Ниже перечислены самые распространённые «ошибочные» коды статусов HTTP, которые можно получить при работе с веб-приложением:

  • 400 — Bad Request. Обычно этот статус связан с ошибкой ввода, например, если пользователь вводит некорректный адрес электронной почты.
  • 401 — Unauthorized. Этот статус связан с ситуацией, когда пользователь пытается получить доступ к чему-либо без авторизации там, где авторизация требуется. Также этот код ошибки подходит в ситуации, когда пользователь пытается выполнить действие, на которое у него нет прав.
  • 403 — Forbidden. Разница между этим статусом и статусом 400 незначительная. Обычно код 403 говорит о том, что сервер понял запрос, но не может его выполнить. Например, такой статус можно возвращать, если пользователь ввёл номер акционного купона с истекшим сроком действия.
  • 404 — Not Found. Это самый известный из «ошибочных» кодов ответа. Он сообщает, что запрошенный ресурс не найден. Это может произойти из-за некорректного URL, удалённой или перемещённой страницы.
  • 500 — Internal Server Error. Этот статус говорит об ошибке, которую можно описать так: «Что-то пошло не так, но мы не знаем, что именно».
  • 503 — Unavailable. Сервер вышел из строя, ошибка может быть запланированной или незапланированной.

Если вы хорошо знаете эти коды, вам будет проще обрабатывать ошибки, которые возникают при работе с AJAX-запросами.

Примечание — Обратите внимание на сервис httpstat.us, он пригодится вам для тестирования реакций на ошибки при разработке фронтенд-приложений.

Обработка ошибок в бэкенд- и фронтенд-приложениях

Обработка ожидаемых ошибок в бэкенде веб-приложений обычно происходит так: приложение отвечает сообщением об ошибке или отображает это сообщение пользователю. Неожиданные ошибки ломают нормальный процесс ответа и приводят к отображению общей страницы ошибки.

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

У фронтенд-приложений нет встроенного механизма, позволяющего остановить работу и показать сообщение об ошибке. После возникновения ошибки в JavaScript обычно происходит одно из описанных ниже событий:

  • Приложение работает, но не выполняет действий, которые ожидает пользователь. Самая распространённая реакция пользователей в такой ситуации — попробовать ещё раз в надежде, что в этот раз приложение поведёт себя ожидаемо.
  • Приложение останавливается, но не сообщает об остановке пользователю. Здесь пользователь повторит действие или попробует выполнить новое действие, но у него ничего не получится.
  • Если ошибка происходит достаточно рано, пользователь может увидеть белый экран из-за неудачной попытки приложения отобразить страницу.

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

Читайте полезную статью
Что такое магические числа в программировании и как снять это заклятие.

Коды возврата

Возврат ошибки связан с тем, что мы возвращаем не просто false или undefined. Мы возвращаем некоторое число. Оно говорит о том, какая ошибка произошла. Это работает так:

// Вызываем команду, например, удаление директории, и получаем результат

// Проверяем, является ли результат частью списка ошибок. Перечисляем возможные варианты
/* errors list */

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

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

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

СемантикаПравить

Родительский и дочерний процессы могут по-своему интерпретировать различные коды возврата. Например, существует общепринятая практика возвращать ноль в случае успешного выполнения дочернего процесса. Также родительский процесс может узнать причину аварийного завершения — например, прерывание работы из-за получения сигнала.

Точное множество возвращаемых кодов определяется каждой программой по-своему. Во многих системах чем больше значение целочисленного кода возврата, тем более серьёзной была причина ошибки. Другой часто используемый приём — передача набора флагов путём установки отдельных битов, как это делает утилита fsck.

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

В AmigaOS определено три уровня кодов возврата

Shell и языки сценариев

Код возврата утилиты, вызванной и из командной строки, является результатом совершения системного вызова waitid или его эквивалента. Полный 32-битный код возврата доступен только через вызов waitid, а более старые интерфейсы возвращают число с обрезанным до одного байта значением.

С точки зрения командных оболочек, команда с нулевым кодом возврата завершилась успешно, а с ненулевым — неудачно. В результате возникает нелогичная ситуация, когда есть один стандартный способ сообщить об успешном завершении и большой выбор различных способов перечисления причин ошибки. Если команда завершилась после получения сигнала с номером N, командная оболочка присвоит переменной $? значение выше, чем 128. Большинство командных оболочек используют значение 128+N, но ksh93 использует 256+N.

Читайте также:  Что означает код ошибки 277 в роблокс

Если команда не найдена, командная оболочка должна вернуть число 127. Если команда найдена, но не является исполняемой, то возвращается 126. Однако, не все командные оболочки соблюдают эти правила.

Если команда завершилась неудачно из-за ошибки в момент разворачивания выражений или перенаправления, код возврата будет больше нуля.

В терминологии DOS, errorlevel — это целочисленное выходное значение, возвращаемое исполняемой программой:

mov ah, 4Chmov al, xxint 21h
где xx – код возврата в диапазоне от 00h до 0FFh

Подход, при котором мы возвращаем либо false, либо данные, подразумевает, что у нас есть два состояния. Но это не всегда так.

Например, если мы возвращаем ошибку файловой системы, то обычно хотим знать, что за ошибка произошла. Например, в файловых системах в UNIXO количество ошибок превышает 100:

/* Operation not permitted */
/* No such file or directory */
/* No such process */
/* Interrupted system call */
/* I/O error */
/* No such device or address */
/* Arg list too long */
/* Exec format error */
/* Bad file number */
/* No child processes */

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

В этом случае появляется вопрос, как действовать — как возвращать результат. Один из самых простых вариантов — это коды возврата.

Как правильно обрабатывать ошибки

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

Один из простых способов обработки ошибок заключается в том, чтобы создать общую схему для реакции на все ошибки и использовать систему событий браузеров, чтобы перехватывать всплывающие ошибки и обрабатывать их. Например, ошибку валидации формы можно перехватить на элементе form или соответствующем инпуте и показать пользователю сообщение об этой ошибке. А нераспознанная системная ошибка может всплыть на уровень document. В этом случае пользователь увидит обобщённое сообщение об ошибке.

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

При обработке ошибок на стороне клиента часто возникает необходимость выбрать между остановкой и продолжением работы приложения. Если ошибка влияет только на часть системы, можно разрешить человеку пользоваться приложением дальше. Если ошибка критическая или она влияет на разные части приложения, можно показать сообщение в модальном окне, которое невозможно закрыть. Также можно заменить контент страницы сообщением об ошибке. Это защитит пользователя от бесполезных попыток выполнить желаемое действие.

Как перехватывать ошибки во фронтенд-приложениях

Вы можете определить обработчик глобально с помощью функции window.onerror. В этом случае обработчик переопределит дефолтное поведение браузеров, благодаря чему ваше приложение будет показывать пользователям полезную информацию при возникновении ошибок.

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

// показываем сообщение об ошибке пользователю

// возвращаем true и запускаем дефолтную
// реакцию приложения на фатальные ошибки

// запускаем дефолтную обработку ошибок браузером

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

Изучайте фронтенд-разработку на Хекслете! Первые курсы в профессии «Фронтенд-программист» доступны бесплатно. Регистрируйтесь и стартуйте в удобное время.

СсылкиПравить

Основные документы по протоколу HTTP (по убыванию даты публикации)

  • Hypertext Transfer Protocol (HTTP) Status Code Registry . IANA (17 октября 2007). — реестр кодов состояния HTTP. Дата обращения: 30 июля 2009. Архивировано 17 февраля 2012 года.
  • RFC 2616 Draft standard «Hypertext Transfer Protocol — HTTP/1.1» (англ.) (с  «Протокол передачи гипертекста — HTTP/1.1»); IETF, июнь 1999; Fielding Roy (), Gettys Jim (Compaq/W3C), Mogul J. (Compaq), (MIT/W3C), Masinter L. (Xerox), Leach P. (Microsoft), Berners-Lee Tim (W3C/MIT)  — обновление протокола HTTP версии 1.1.
  • RFC 2068 Proposed standard «Hypertext Transfer Protocol — HTTP/1.1» (англ.) (с  «Протокол передачи гипертекста — HTTP/1.1»); IETF, январь 1997; Fielding Roy (), Gettys Jim (DEC), Mogul J. (DEC), (MIT/LCS), Berners-Lee Tim (MIT/LCS) — ранняя спецификация по HTTP версии 1.1.
  • RFC 1945 Informational «Hypertext Transfer Protocol — HTTP/1.0» (англ.) (с  «Протокол передачи гипертекста — HTTP/1.0»); IETF, май 1996; Berners-Lee Tim (MIT/LCS), Fielding Roy (), (MIT/LCS) — самая первая спецификация по протоколу HTTP. Так же включает в себя описание HTTP/0.9.

Документы по расширениям и обновлениям протокола HTTP (по убыванию даты публикации)

  • RFC 4918 Proposed Standard «HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)» (англ.) (с  «Расширения HTTP для распределённой авторской работы и управления версиями через веб (WebDAV)»); IETF, июнь 2007; Dusseault Ed. L. () — поздняя спецификация по протоколу WebDAV, заместившая RFC 2518.
  • RFC 3229 Proposed standard «Delta encoding in HTTP» (англ.) (с  «Дельта-кодирование в HTTP»); IETF, январь 2002; Mogul J. (Compaq WRL), Krishnamurthy B. (AT&T), Douglis F. (AT&T), Feldmann A. (Univ. of Saarbrücken), Goland Y. (Marimba), van Hoff A. (Marimba), Hellerstein D. (ERS/USDA).
  • RFC 2817 Proposed Standard «Upgrading to TLS Within HTTP/1.1» (англ.) (с  «Обновление к TLS совместно с HTTP/1.1»); IETF, май 2000; (4K Associates/), Lawrence S. (Agranat Systems, Inc.) — обновление к RFC 2616 для описания работы HTTP и TLS.
  • RFC 2774 Experimental «An HTTP Extension Framework» (англ.) (с  «Каркас расширений HTTP»); IETF, февраль 2000; Nielsen H. (Microsoft), Leach P. (Microsoft), Lawrence S. (Agranat Systems).
  • Internet Draft «WebDAV Advanced Collections Protocol» (с  «Протокол продвинутых коллекций WebDAV»); IETF, 18 июня 1999; Slein J. (Xerox), Whitehead Jr. E. J. (), Davis J. (CourseNet), Clemm G. (Rational), Fay C. (), Crawford J. (IBM), Chihaya T. (DataChannel)  — управление коллекциями в WebDAV; просрочился 18 декабря 1999 года.
  • RFC 2518 Proposed Standard «HTTP Extensions for Distributed Authoring — WEBDAV» (англ.) (с  «Расширения HTTP для распределённой авторской работы — WEBDAV»); IETF, февраль 1999; Goland Y. (Microsoft), Whitehead E. (), Faizi A. (Netscape), Carter S. (Novell), Jensen D. (Novell) — первая спецификация по протоколу WebDAV (замещена RFC 4918).
  • RFC 2295 Experimental «Transparent Content Negotiation in HTTP» (англ.) (с  «Прозрачное согласование содержимого в HTTP»); IETF, март 1998; Holtman K. (TUE), Mutz A. (Hewlett-Packard).
  • Web Distributed Authoring and Versioning (WebDAV) Protocol: Client Extensions . Microsoft (14 марта 2007). — описание поддержки клиентских расширений в протоколе WebDAV. Дата обращения: 30 июля 2009. Архивировано 17 февраля 2012 года.
  • RFC 2324 Informational «Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)» (англ.) (с  «Гипертекстовый протокол управления кофеваркой (HTCPCP/1.0)»); IETF, 1 апреля 1998; Masinter L..
  • KB 318380 Коды состояния служб IIS. Microsoft (4 декабря 2007). — список расширенных кодов состояния для протоколов HTTP и FTP. Дата обращения: 16 января 2010. Архивировано 17 февраля 2012 года.
  • Справочник по кодам статуса HTTP. Яндекс. — обработка кодов состояния HTTP роботами Яндекса. Дата обращения: 2 мая 2018.
Читайте также:  Код ошибки memori management

Главное об обработке ошибок во фронтенд-приложениях

Главный факт об обработке ошибок заключается в том, что вы должны их обрабатывать. Любая попытка сообщить пользователю что-то полезное, когда возникает ошибка — отличный ход. Даже информирование с помощью alert() лучше, чем отсутствие информации. Помните, что при проектировании UI вашего приложения нужно учитывать все возможные ситуации, включая различные ошибки.

Адаптированный перевод статьи Front-End Error Handling by Static Apps. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.

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

/* попытка открыть файл на чтение */

/* если файл не может быть открыт, напечатать номер ошибки и сообщение*/

“Cannot open file, error %d, %s
/* Альтернативно можно использовать perror(), который обеспечивает ту же функциональность */
“Cannot open file”

Так как обычно коды ошибок — глобальные переменные, то они могут быть доступны из любой точки программы. Так же как и с другими глобальными переменными, эта простота доступа может быть источником проблем в многопоточной среде. В связи с тем, что в глобальные переменные могут записывать одновременно несколько потоков, это может привести к состоянию гонки. Для решения этой проблемы, POSIX определяет переменную errno как переменную локальную к потоку (thread-local variable).

  • Article «Errors: errno in UNIX programs» by Chris Herborth
  • Article «Exception Handling in C without C++» by Tom Schotland and Peter Petersen
  • Article «Error codes or Exceptions? Why is Reliable Software so Hard?» by Damien Katz
  • Win32 Error Handling Functions
  • Error Code Library
  • Error Lookup

Обзорный списокПравить

Ниже представлен обзорный список всех описанных в данной статье кодов ответа:

Диаграмма принятия веб-сервером решений на основе заголовков

Статистика по кодам ответа, сгенерированная анализатором логов Webalizer

Возврат результата в Golang

Рассмотрим более продвинутый способ. Этот тот же способ, что и в СИ, но улучшенный. Он называется Golang Style.

Golang — это современный язык, который избавляет от глобальных переменных.

// Возращается два значения: dat — данные, err — ошибка

// Проверяем, равна ли ошибка nil

Если ошибка не равна nil, то ошибки нет, и всё хорошо. Если равна nil, то мы обрабатываем ее.

Это фактически такой же подход как в CИ. Только здесь нет глобальной переменной, которая постоянно меняется. Каждая функция возвращает свой результат выполнения. Так мы двигаемся вниз по вызовам и можем строить программу.

Возврат результата в СИ

В Си принят следующий подход возврата результата:

# Открываем файл на чтение

# Делаем проверку
// Value of errno is: 2
# Если указатель равен нулю, то пишем, что произошла ошибка
“Value of errno: %d

Ошибка записывается в глобальную переменную, которая называется errno. И там, например, будет цифра 2, которая означает, что всё плохо.

Здесь мы убеждаемся, что у нас нет адекватного результата. Но по сути идет глобальное изменение среды. А глобальные переменные — это не вариант, особенно, в современных языках.

Возврат результата в JavaScript

В JavaScript можно использовать такой же подход. Это рабочая схема, которая основана на Destructuring. У нее есть определенные недостатки, которые мы разберем в следующем уроке.

// Делаем чтение, описываем данные и ошибку

// do something with data

// handle error

Если ошибка равна null, то делаем все что хотим, если нет, то обрабатываем ошибку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *