Журнал • знания • практикаПоиск по сайту

Сайты, дизайн и самостоятельная работа

Найти материал →

Обработка ошибок в javascript: как показать пользователю понятное сообщение

6 минут чтения

Обработка ошибок в javascript: как показать пользователю понятное сообщение

Понятная обработка ошибок в 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 "Не удалось выполнить действие. Проверьте соединение и повторите попытку.";
}

Что сообщать пользователю при сетевой ошибке или тайм-ауте

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

  1. Определите, что именно не удалось.
    Различайте отсутствие ответа, тайм-аут, ошибочный ответ сервера и неверные данные. Не сообщайте причину точнее, чем позволяет клиентская проверка.
  2. Остановите или завершите ожидание.
    При тайм-ауте отмените зависший запрос, если это предусмотрено сценарием. Например, AbortController позволяет передать сигнал отмены в fetch.
  3. Покажите понятное сообщение.
    Укажите, какое действие не завершилось, и предложите подходящий следующий шаг: повторить запрос, проверить соединение или обратиться в поддержку.

    • Для временной сетевой ошибки подойдёт: "Не удалось сохранить изменения. Проверьте соединение и попробуйте ещё раз".
    • Если действие могло выполниться на сервере, не утверждайте, что оно точно не состоялось.
  4. Сохраните данные и контекст.
    Оставьте введённое в форме и обозначьте незавершённое действие. Не сбрасывайте поля, пока пользователь явно не подтвердил отмену или очистку.
  5. Предложите безопасное продолжение.
    Разрешите повторить запрос, если повтор не создаст дубликат и состояние можно проверить. В остальных случаях предложите обновить данные или выбрать другой путь.

Быстрый режим

  1. Перехватите ошибку у действия, которое могло завершиться сбоем.
  2. Определите, безопасно ли повторять запрос.
  3. Покажите краткое сообщение и сохраните введённые данные.
  4. Запишите технические детали без секретов и персональных данных.

Как разместить уведомление и сохранить контекст действия

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

  • Уведомление находится рядом с полем или действием, к которому относится.
  • Текст сообщает, что не получилось, и предлагает следующий шаг.
  • Сообщение заметно, но не перекрывает форму и основное управление.
  • Введённые значения остаются на месте после сбоя.
  • При повторной отправке видно, что запрос выполняется, а кнопка защищена от случайных повторов.
  • После успеха сообщение об ошибке исчезает или заменяется подтверждением.
  • Важное сообщение доступно вспомогательным технологиям, например через подходящую область aria-live.

Для вывода ошибок JavaScript не вставляйте непроверенные строки через innerHTML. Используйте текстовый узел или textContent, чтобы сообщение не интерпретировалось как разметка.

Когда повторять запрос, а когда предложить другой выход

Типичные ошибки при реализации реакции на сбой:

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

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

Как логировать сбои и проверять сценарии отказа

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

  • Локальная диагностика: console.error подходит для разработки и отладки. Не оставляйте в производственной версии лишние подробности или секреты.
  • Централизованный сбор ошибок: используйте подключённый в проекте инструмент, если он настроен; перед отправкой исключите токены и другие чувствительные данные.
  • Проверки в тестах: моделируйте сетевой сбой, тайм-аут, ошибочный ответ и успешное восстановление, чтобы проверить тексты и состояние формы.
  • Ручная проверка: отключите сеть или используйте тестовый ответ с ошибкой и проверьте, что пользователь видит безопасное сообщение и может продолжить работу.
function reportError(error) {
  console.error("Не удалось выполнить запрос", {
    name: error.name
  });
}

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

Тонкости обработки ошибок в реальном интерфейсе

Где лучше перехватывать ошибку из обработчика кнопки?

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

Можно ли показывать пользователю текст из error.message?

Обычно нет: он может содержать технические подробности или быть непонятным. Преобразуйте известные причины в безопасные и ясные формулировки.

Нужно ли повторять запрос после тайм-аута автоматически?

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

Как не потерять данные формы при ошибке?

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

Чем отличается сообщение об ошибке от записи в журнале?

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

Как проверить обработку ошибок без реального сбоя сервера?

В тестах подмените ответ API или сеть и проверьте сообщение, сохранение введённого и доступность повторного действия. Для ручной проверки используйте отключение сети или тестовый сценарий отказа.

Scroll to Top