Обработка исключений

Текущие проблемы и соглашения по обработке исключений в сервисах X.

На данный момент у нас в коде замешалось 2 понятия: ошибка и исключение.

Ошибки

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

Исключения

Исключение – можно разделить на 2 вида:

Неожидаемые

Неожидаемые – случаются неконтролируемо и никак не обрабатываются в коде. Такие исключения должны автоматически отсылаться в Sentry и разбираться командой разработки.

Кастомные

Кастомные – исключения, которые разработчики заложили в коде сервиса, которые имеют конкретное сообщение об ошибке и используются для прерывания выполняемой логики. Такие исключения ловятся на уровне выше (например, middleware или application layer) и обрабатываются желаемым образом. При их выкидывании не нужно отправлять события в Sentry, а достаточно вернуть сообщение об ошибке пользователю. В ситуациях, когда сообщение об ошибке нельзя трактовать однозначно, стоит дополнительно логировать ситуацию с уровнем ERROR и контекстом. Пример: выкидываем исключение об ошибке аутентификации → ловим его выше по стеку → формируем ответ в JSON-формате с сообщением "Не удалось войти в систему. Пожалуйста проверьте ваши логин и пароль." (чтобы уменьшить риск взлома мы не расскрываем деталей почему не удалось войти в X) → пишем в лог ошибок "Пользователь [внутренний-идентификатор] неправильно ввел пароль".

Отправка исключений в Sentry

Для отправки исключений в Sentry используйте метод расширения SendExceptionToSentry.

Также у нас имеется класс SentryUserFactory, который расширяет сведения о пользователе при отправке исключений в Sentry. Этот класс будет использован только в том случае, когда в конфигурации сервиса (appsettings.json или ENV) для Sentry задана отправка личной информации пользователя (Personally Identifiable Information - PIII):

"SendDefaultPii": true

Этот класс переопределяет поведение по умолчанию в случае SendDefaultPii=true. Без него - сбор PII будет дефолтным (в т.ч. будут попадать email-ы пользователей в Sentry).

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

Последнее обновление