Перевод страницы с английского оригинала. При расхождениях приоритет имеет английская версия.
Ошибки и problem+json
В DaloyJS ошибки являются полноценной частью фреймворка. Каждый выброшенный HttpError сериализуется в RFC 9457 problem+json со стабильным URI в type, идентификатором запроса и подходящим Content-Type.
- 01обработчикthrow new NotFoundError(...)любой подкласс HttpError
- 02фреймворкСопоставление с полями RFC 9457type · title · status · detail
- 03продакшенСкрытие detail у 5xxпоказывается только в окружении development или test
- 04сетьСериализованный ответapplication/problem+json + x-request-id
Встроенные классы ошибок
TooManyRequestsError и ServiceUnavailableError одинаково проверяют retryAfterSeconds: всё, что не является неотрицательным безопасным целым числом, вызывает RangeError при создании, поэтому NaN из отсутствующей переменной окружения никогда не превратится в некорректный заголовок Retry-After. RequestTimeoutError (дедлайн requestTimeoutMs, см. requestTimeoutStatus, на английском) начиная с 1.16.0 имеет no-store для каждого варианта статуса, поэтому общий кэш не продолжит отдавать 503/504 после восстановления бэкенда. Голый new HttpError(status, …) получает type проблемы вида https://httpstatuses.io/<status>; встроенные классы несут стабильные URI https://daloyjs.dev/errors/<slug>.
Выброс ошибки в обработчике
Формат ответа
Идентификатор запроса возвращается клиенту в двух местах: в заголовке ответа x-request-id и (согласно RFC 9457 §3.1) в поле instance документа проблемы в виде URN urn:request:<uuid>. Свойства requestId верхнего уровня нет: клиенты должны читать заголовок или разбирать URN из instance.
Скрытие деталей в продакшене
DaloyJS убирает поле detail из любого ответа 5xx, если окружение не является однозначно development или test, чтобы внутренние сообщения об ошибках и фрагменты SQL не утекали к клиентам. Полная ошибка всё равно передаётся вашему логгеру и хуку onError.
| Конфигурация | detail у 5xx |
|---|---|
env: "development" или env: "test" | показывается |
нет env, NODE_ENV=development или test | показывается |
нет env, NODE_ENV не задан, пуст или имеет любое другое значение | скрыт |
env: "production", production: true или NODE_ENV=production | скрыт |
production: false при незаданном NODE_ENV | скрыт |
Незаданное окружение намеренно приводит к закрытому поведению. В edge-рантаймах, таких как Cloudflare Workers и Deno Deploy, нет NODE_ENV, и если считать это режимом разработки, сообщения исключений уходили бы клиентам. daloy dev выставляет NODE_ENV=development для дочернего процесса, если вы его не задали, поэтому при локальной разработке детали по-прежнему видны. Ошибки, которые вы сериализуете сами (например, тело ответа, собранное из err.message в блоке catch), не скрываются. Вместо этого выбрасывайте их или выбрасывайте HttpError с безопасным detail.
Собственные классы ошибок
Все встроенные классы выше задают type вида https://daloyjs.dev/errors/<slug>. Простой HttpError, выброшенный без type, откатывается к https://httpstatuses.io/<status>. Собственный middleware фреймворка, отвечающий 503 (loadShedding(), concurrencyLimit(), requestTimeoutStatus: 503), задаёт свой type на daloyjs.dev, так что запасной вариант применяется только к ошибкам, которые вы создаёте сами. Задавайте type, если клиенты на него опираются, или используйте встроенный класс:
Сервис недоступен
Для режима обслуживания, сбоя зависимости или выводимого из работы экземпляра выбрасывайте ServiceUnavailableError. Он отвечает 503 со стабильным type https://daloyjs.dev/errors/service-unavailable, необязательным Retry-After и cache-control: no-store, поэтому CDN не продолжит отдавать ответ о сбое после восстановления.
retryAfterSeconds должен быть неотрицательным целым числом. Всё остальное (NaN из отсутствующей переменной окружения, -1, 1.5) вызывает RangeError вместо отправки некорректного заголовка Retry-After.
Собственный onError
Последнее обновление: