# Backend errors ## Поток ```text application/domain outcome → application mapping → HttpExceptionFilter → application/problem+json ``` Сохраняй принятый профиль RFC 9457: `status`, стабильный публичный `code`, для validation — `errors: [{ pointer, detail }]`. Точный контракт validation описан в [HTTP API](http-api.md#источник-контракта). Не добавляй `type/title/instance` как обязательные поля без contract change. Чистый domain не импортирует Nest HTTP exceptions. Существующий application service может бросить подходящий `HttpException` с public code; не нужен новый error framework/registry. Если domain outcome требует HTTP interpretation, маппинг принадлежит application/transport boundary. ## Codes и безопасность - Используй existing code владельца, не сравнивай внутренние сообщения. Новое значение имеет один symbolic owner; metadata/validation и consumers согласуются по [domain values](engineering.md#domain-values). - Общий envelope, default status mapping и unexpected errors принадлежат [HttpExceptionFilter](../../src/common/filters/http-exception.filter.ts). Не дублируй `res.status().json()` в controllers/services. - Неожиданный exception → `500 / INTERNAL_SERVER_ERROR`, без message/stack, SQL, credentials или raw upstream payload в ответе. - External auth failure и временная недоступность имеют разные outcomes; translation выполняется на existing integration/access boundary. - Логи используют [observability](observability.md). Redaction не делает произвольное сообщение ошибки безопасным. ## Проверка Для изменённого кода проверь observable status/code и сохранность данных. Для validation нужен request через `configureApp`: fabricated `ValidationError` в unit test filter не доказывает форму, выходящую из реального ValidationPipe. OpenAPI parity проверяет schema, а не response pipeline; [Testing](testing.md).