01 апр. 2025 г.·7 мин чтения

Обработка ошибок во фронтенде, которая помогает поддержке быстрее решать проблемы

Обработка ошибок во фронтенде должна разделять ошибки ввода, сбои сервера и устаревшее состояние, чтобы пользователи видели понятные сообщения, а поддержка получала полезные отчеты.

Обработка ошибок во фронтенде, которая помогает поддержке быстрее решать проблемы

Почему одно общее сообщение об ошибке создает проблемы

Всплывающее уведомление с текстом «Что-то пошло не так» кажется безобидным, но оно блокирует следующий шаг для всех.

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

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

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

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

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

Хорошая обработка ошибок решает это, пока приложение еще помнит действие, состояние формы и ответ, который оно получило. Вместо «у вас сломано приложение» поддержка начинает получать такие сообщения, как «сохранение не удалось после того, как я изменил поле email» или «я редактировал запись по старым данным, пока не обновил страницу». Это быстро убирает догадки.

Разделите ошибки на три группы

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

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

Ошибка формы означает, что пользователь может исправить проблему на том же экране. Неверный формат email, пустое обязательное поле или бессмысленная дата. Держите сообщение рядом с полем, объясняйте, что нужно изменить, и дайте пользователю попробовать еще раз.

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

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

Эти три группы должны вести к трем понятным действиям:

  • Ошибка формы: исправьте поле и отправьте снова
  • Ошибка сервера: повторите попытку или сообщите о проблеме
  • Устаревшая страница: обновите данные и проверьте недавние изменения

Такое соответствие сразу помогает поддержке. Когда пользователь говорит: «У меня ошибка устаревшей страницы», агент уже знает, что не нужно просить его очистить все поля и начать сначала.

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

Что должен видеть пользователь для каждого типа

Пользователи могут восстановиться после большинства ошибок, если экран говорит правду простыми словами. Общие всплывающие сообщения здесь не помогают. Хорошие сообщения объясняют, что произошло, что не произошло и что делать дальше.

Для ошибок пользователя держите сообщение рядом с полем. Если в email не хватает «@», скажите об этом рядом с полем email. Если дата указана в неверном формате, покажите нужный формат и оставьте введенное значение на месте, чтобы человек мог исправить одну вещь и двигаться дальше.

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

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

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

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

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

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

Пошагово: как построить понятный поток ошибок

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

Простой порядок сборки работает лучше, чем хитрый код.

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

Затем дайте каждому сбою одну категорию в коде: ошибка ввода, ошибка сервера или устаревшее состояние клиента. Неверный формат email относится к первой группе. Ответ 500 — ко второй. Форма, отредактированная на старых данных, — к третьей.

Используйте одну и ту же структуру ошибки везде. Сделайте ее небольшой и одинаковой, с полями вроде type, code, message, requestId и details. Интерфейс сможет ее прочитать, логи — сохранить, а поддержка — найти.

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

Каждый раз добавляйте контекст. Указывайте request ID, название страницы, user ID или account ID и действие, которое не удалось. Если поддержка получает отчет «сохранение не удалось на редактировании клиента» с request ID, она обычно может найти проблему за минуты, а не гадать.

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

Хорошая проверка проста. Каждое сообщение об ошибке должно отвечать на один вопрос. Для пользователя это «Что мне делать сейчас?». Для поддержки — «Что именно сломалось и где?». Если ваш поток отвечает на оба, отчетов, которые упираются в тупик, становится меньше.

Что нужно поддержке в каждом отчете

Исправьте свой поток ошибок
Разберите ошибки ввода, сбои сервера и проблемы устаревшей страницы с опытным Fractional CTO.

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

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

Полезный отчет включает пять вещей:

  • действие, которое пытался выполнить пользователь, например «сохранил изменения в записи клиента»
  • точный текст, показанный на экране, дословно
  • время, когда произошла ошибка, с часовым поясом, если ваши пользователи работают в разных регионах
  • request ID или trace ID, связанный с этим неудачным действием
  • изменился ли результат после повторной попытки, обновления страницы или правки ввода

Каждый пункт экономит реальное время. Точный текст помогает поддержке отличить одну ошибку от другой. Время позволяет искать в логах без догадок. Request ID указывает на один конкретный неудачный запрос, а не на весь поток трафика. Заметка о том, что помогло, часто оказывается самым быстрым подсказчиком.

Например, пользователь обновляет номер телефона клиента и нажимает «Сохранить». Приложение сообщает: «Проверка не пройдена: неверный формат телефона», а также время и request ID. Теперь поддержка понимает, что это, скорее всего, ошибка ввода, а не сбой сервера. Если же в отчете сказано, что сохранение не удалось, обновление страницы помогло, а вторая попытка сработала, поддержке стоит проверить устаревшее состояние клиента или кэширование, прежде чем смотреть на правила бэкенда.

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

Реальный пример: редактирование карточки клиента

Менеджер по продажам открывает карточку клиента и меняет адрес email. По ошибке она вводит alex@@company.com. Приложение должно поймать это еще до того, как что-то уйдет на сервер.

Здесь лучше работает встроенное сообщение в поле, а не всплывающее уведомление. Подсветите поле email, простыми словами объясните, что не так, и оставьте черновик на месте, чтобы можно было исправить его за секунду. Это ошибка ввода, и браузер может обработать ее сразу.

Она исправляет email и нажимает «Сохранить» еще раз. На этот раз формат верный, поэтому запрос уходит. Потом API возвращает ошибку 500.

Теперь сообщение должно полностью измениться. Не указывайте снова на поле email, потому что с ним уже все в порядке. Скажите, что сохранение не удалось на сервере, оставьте изменения на экране и дайте безопасную возможность повторить попытку. Короткого сообщения вроде «Не удалось сохранить изменения. Ничего не потеряно» достаточно.

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

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

За одну короткую сессию редактирования у вас уже есть три разных типа ошибок:

  • ошибка проверки поля до сохранения
  • сбой сервера во время сохранения
  • конфликт версий после того, как запись изменил кто-то другой

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

Ошибки, которые зря тратят время поддержки

Согласуйте продукт и поддержку
Oleg может вместе посмотреть на фронтенд, бэкенд и путь поддержки, чтобы проблемы перестали кочевать между командами.

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

Первая ошибка — это общее всплывающее сообщение. Если приложение показывает «Что-то пошло не так» и при неверном адресе email, и при таймауте, и при конфликте редактирования, пользователи сообщают о всех трех случаях одинаково. Поддержке потом приходится гадать, нужно ли просить исправить форму, попробовать позже или обновить свежие данные.

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

Удалять черновик пользователя после ошибки — еще хуже. Людей не волнует, в браузере проблема или на сервере. Их волнует, что десять минут правок исчезли. Оставляйте черновик на экране, сохраняйте измененные поля и делайте повторную отправку простой после устранения проблемы.

Несколько шаблонов вызывают большую часть боли. Одно сообщение охватывает все типы ошибок. Приложение просит повторить попытку там, где нужно исправить форму. Экран сбрасывается и убирает несохраненные изменения. Логи хранят только «сохранение не удалось» без request ID, кода статуса или ID записи. Старые данные клиента вызывают то же сообщение, что и реальный сбой сервера.

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

Логи не менее важны, чем сообщение для пользователя. Поддержке нужно достаточно деталей, чтобы быстро отсортировать обращение: какое действие не удалось, какую запись трогал пользователь, вернул ли сервер 400, 409 или 500, и было ли состояние клиента устаревшим. Спрячете эти детали — и каждый тикет превратится в длинный обмен сообщениями.

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

Короткая проверка перед запуском

Улучшите отчетность об ошибках
Проверьте request ID, обработку конфликтов и сценарии повторной попытки с человеком, который запускает продакшен-системы.

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

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

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

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

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

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

Что делать дальше

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

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

Затем перепишите сообщения так, чтобы каждое вело к действию. «Введите действительный адрес электронной почты» — ясно. «Не удалось сохранить изменения. Попробуйте еще раз» полезно лишь наполовину, если вы не говорите, остался ли черновик на месте. Для устаревших данных говорите прямо: запись изменилась в другом месте, поэтому перед повторным сохранением страницу нужно обновить.

Простое поле для отчета помогает больше, чем еще одно всплывающее сообщение. Дайте пользователям возможность скопировать короткий блок в обращение в поддержку: название экрана, ID записи или клиента, request ID или error ID, время, версию приложения, браузер и действие, которое они сделали. Сделайте текст достаточно коротким, чтобы люди действительно его отправляли.

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

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

Если вашей команде нужен второй взгляд на категории, отчеты и поток приложения, Oleg на oleg.is работает со стартапами и небольшими компаниями как Fractional CTO и консультант. Короткого разбора одной загруженной страницы часто достаточно, чтобы увидеть первые исправления.

Часто задаваемые вопросы

Почему сообщение «Что-то пошло не так» — плохой вариант?

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

Какие типы ошибок стоит использовать в интерфейсе?

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

Как показывать ошибку проверки формы?

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

Что должно быть в сообщении об ошибке сервера?

Скажите пользователю, что действие не удалось из-за сервера, и дайте понять, что форму он не сломал. Оставьте введенные данные на экране, предложите повторить попытку и покажите request ID или время, если они есть.

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

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

Нужно ли сохранять ввод пользователя после ошибки?

Да, если можете, сохраняйте черновик. Люди ценят свою работу больше, чем техническую причину сбоя, поэтому не стирайте отредактированные поля после таймаута, 500 или предложения повторить попытку.

Что должно быть в каждом обращении в поддержку?

Добавьте, что пользователь пытался сделать, точный текст на экране, время события и request ID, связанный с этим действием. Еще полезно указать, помогли ли повторная попытка, обновление страницы или изменение ввода, потому что именно эта деталь часто быстрее всего подсказывает причину.

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

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

Как протестировать обработку ошибок до запуска?

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

С чего начать, если я хочу улучшить обработку ошибок?

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