
Понятная обработка ошибок в JavaScript начинается с перехвата сбоя в подходящем месте, затем переводит техническую причину в безопасное сообщение и предлагает пользователю следующий шаг. Не показывайте стек вызовов или внутренние данные. Сохраняйте введённое, обозначайте, что именно не удалось, и позволяйте повторить действие, когда это безопасно.
Правила, которые делают ошибки понятными и безопасными
- Перехватывайте ожидаемые сбои рядом с действием, которое может завершиться неудачно.
- Отделяйте текст для пользователя от технических сведений для журнала.
- Объясняйте, что произошло и что пользователь может сделать дальше.
- Не стирайте введённые данные и не повторяйте запрос автоматически без проверки последствий.
- Для валидации формы JavaScript показывайте подсказку рядом с конкретным полем.
Где перехватывать ошибки: try/catch, события и границы компонентов
Используйте try/catch вокруг асинхронных операций и участков кода, где можно обработать ожидаемый сбой: например, отправку формы или чтение ответа сервера. В обработчике события перехватывайте ошибку, чтобы показать локальное сообщение и сохранить состояние интерфейса.
async function loadProfile() {
try {
const response = await fetch("/api/profile");
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
reportError(error);
showMessage("Не удалось загрузить профиль. Попробуйте ещё раз.");
}
}
В приложении с компонентной архитектурой граница ошибок может остановить распространение сбоя в дочернем интерфейсе и показать запасной экран. Она не заменяет локальную обработку действий пользователя. Не добавляйте пустой catch и не перехватывайте ошибку только для того, чтобы скрыть её: сбой должен быть обработан или передан дальше.
Обработка ошибок JavaScript полезна, когда интерфейс может дать пользователю осмысленный следующий шаг. Для ошибок, которые нельзя исправить на клиенте, не имитируйте успешное завершение: покажите состояние сбоя и сохраните детали для диагностики.
Как превратить техническую причину сбоя в ясное сообщение
До реализации определите, кто отвечает за каждую часть реакции: обработчик действия, компонент уведомления и система журналирования. Понадобятся доступ к коду интерфейса, понятные сценарии ошибок API и способ проверить сетевой сбой. Если проект использует централизованный журнал ошибок, уточните, какие данные разрешено в него передавать.
- Техническая причина: исключение, код ответа или состояние сети - для диагностики.
- Сообщение пользователю: краткое описание результата и доступное действие.
- Контекст: операция, время и безопасный идентификатор события, если он предусмотрен проектом.
Не выводите пользователю необработанное error.message: оно может быть непонятным или содержать внутренние сведения. В пользовательском сообщении избегайте адресов API, токенов, имён файлов сервера и стека вызовов.
function getUserMessage(error) {
if (error.name === "AbortError") {
return "Запрос занял слишком много времени. Попробуйте ещё раз.";
}
return "Не удалось выполнить действие. Проверьте соединение и повторите попытку.";
}
Что сообщать пользователю при сетевой ошибке или тайм-ауте
Путь обработки ошибки состоит из последовательных шагов: обнаружить сбой, определить безопасную реакцию и сообщить о ней без потери контекста.
-
Определите, что именно не удалось.
Различайте отсутствие ответа, тайм-аут, ошибочный ответ сервера и неверные данные. Не сообщайте причину точнее, чем позволяет клиентская проверка. -
Остановите или завершите ожидание.
При тайм-ауте отмените зависший запрос, если это предусмотрено сценарием. Например,AbortControllerпозволяет передать сигнал отмены вfetch. -
Покажите понятное сообщение.
Укажите, какое действие не завершилось, и предложите подходящий следующий шаг: повторить запрос, проверить соединение или обратиться в поддержку.- Для временной сетевой ошибки подойдёт: "Не удалось сохранить изменения. Проверьте соединение и попробуйте ещё раз".
- Если действие могло выполниться на сервере, не утверждайте, что оно точно не состоялось.
-
Сохраните данные и контекст.
Оставьте введённое в форме и обозначьте незавершённое действие. Не сбрасывайте поля, пока пользователь явно не подтвердил отмену или очистку. -
Предложите безопасное продолжение.
Разрешите повторить запрос, если повтор не создаст дубликат и состояние можно проверить. В остальных случаях предложите обновить данные или выбрать другой путь.
Быстрый режим
- Перехватите ошибку у действия, которое могло завершиться сбоем.
- Определите, безопасно ли повторять запрос.
- Покажите краткое сообщение и сохраните введённые данные.
- Запишите технические детали без секретов и персональных данных.
Как разместить уведомление и сохранить контекст действия
После реализации проверьте сценарий на разных размерах экрана и убедитесь, что сообщение доступно и не перекрывает важные элементы.
- Уведомление находится рядом с полем или действием, к которому относится.
- Текст сообщает, что не получилось, и предлагает следующий шаг.
- Сообщение заметно, но не перекрывает форму и основное управление.
- Введённые значения остаются на месте после сбоя.
- При повторной отправке видно, что запрос выполняется, а кнопка защищена от случайных повторов.
- После успеха сообщение об ошибке исчезает или заменяется подтверждением.
- Важное сообщение доступно вспомогательным технологиям, например через подходящую область
aria-live.
Для вывода ошибок JavaScript не вставляйте непроверенные строки через innerHTML. Используйте текстовый узел или textContent, чтобы сообщение не интерпретировалось как разметка.
Когда повторять запрос, а когда предложить другой выход
Типичные ошибки при реализации реакции на сбой:
- Автоматически повторять любой запрос, не проверив, не создаст ли это дубликат операции.
- Считать, что при отсутствии ответа сервер точно не обработал действие.
- Показывать одинаковый текст для ошибок сети, валидации и отказа в доступе.
- Скрывать ошибку в пустом
catchили показывать пользователю технический текст исключения. - Очищать поля формы после неудачной отправки.
- Оставлять кнопку заблокированной после завершения запроса с ошибкой.
- Показывать бесконечный индикатор ожидания, не предлагая выхода при тайм-ауте.
Повтор уместен, если операция допускает безопасный повтор и пользователь понимает, что произойдёт. Если результат предыдущей попытки неизвестен, сначала предложите проверить состояние действия или выбрать альтернативу, например вернуться к форме и повторить после уточнения данных.
Как логировать сбои и проверять сценарии отказа
В разработке веб-приложений на JavaScript журналирование помогает понять, где возник сбой, а проверка отказных сценариев - убедиться, что интерфейс не теряет данные и не обещает невозможного. Выбирайте способ по архитектуре и требованиям проекта:
- Локальная диагностика:
console.errorподходит для разработки и отладки. Не оставляйте в производственной версии лишние подробности или секреты. - Централизованный сбор ошибок: используйте подключённый в проекте инструмент, если он настроен; перед отправкой исключите токены и другие чувствительные данные.
- Проверки в тестах: моделируйте сетевой сбой, тайм-аут, ошибочный ответ и успешное восстановление, чтобы проверить тексты и состояние формы.
- Ручная проверка: отключите сеть или используйте тестовый ответ с ошибкой и проверьте, что пользователь видит безопасное сообщение и может продолжить работу.
function reportError(error) {
console.error("Не удалось выполнить запрос", {
name: error.name
});
}
Передавайте в журнал только данные, необходимые для диагностики. Не записывайте пароль, токен авторизации и содержимое формы без отдельного обоснования и разрешённого механизма.
Тонкости обработки ошибок в реальном интерфейсе
Где лучше перехватывать ошибку из обработчика кнопки?
Перехватывайте её в обработчике или вызываемой им функции, если там можно показать конкретное сообщение и сохранить состояние интерфейса. Ошибки, которые компонент не может обработать, передавайте общей границе ошибок.
Можно ли показывать пользователю текст из error.message?
Обычно нет: он может содержать технические подробности или быть непонятным. Преобразуйте известные причины в безопасные и ясные формулировки.
Нужно ли повторять запрос после тайм-аута автоматически?
Только если повтор безопасен и не приведёт к дублированию действия. Если неизвестно, обработал ли сервер предыдущую попытку, сообщите об этом и предложите проверить результат.
Как не потерять данные формы при ошибке?
Не очищайте значения при неудачном ответе и сохраняйте их в текущем состоянии интерфейса. Сброс выполняйте после подтверждённого успеха или явного действия пользователя.
Чем отличается сообщение об ошибке от записи в журнале?
Сообщение объясняет пользователю результат и следующий шаг. Журнал содержит технический контекст для диагностики, но не должен раскрывать секреты и лишние персональные данные.
Как проверить обработку ошибок без реального сбоя сервера?
В тестах подмените ответ API или сеть и проверьте сообщение, сохранение введённого и доступность повторного действия. Для ручной проверки используйте отключение сети или тестовый сценарий отказа.