rockspec_format = '3.0' package = 'tnt-error' version = 'scm-1' source = { url = 'git+https://github.com/tnt-skein/tnt-error.git', branch = 'main', } description = { summary = 'Отказы: каталог кодов, перехват паники, представление наружу', detailed = [[ До человека доходит только то, что ему поможет, остальное — в журнал. Ожидаемый отказ («нет такого клиента», «пароль не подходит») объявлен в каталоге с кодом, статусом ответа и строкой по-русски и уходит наружу целиком. Внутренняя поломка отдаёт опознаватель происшествия и общую фразу, а подробности со стеком остаются в записи журнала, которую находят по тому же опознавателю. Причину накрывают двумя вызовами: wrap — объявленным кодом, explain — готовым словом разработчика. Пакет ничего не решает по виду строки: чужой текст наружу не выходит никогда, даже если он безобиден. guard зовёт функцию под перехватом, и паника становится внутренней поломкой с опознавателем вида 4KJ7-QW9M, который читается вслух по телефону. Ответ по умолчанию имеет вид RFC 9457 (application/problem+json), простой вид и своя функция — настройкой. Браузеру, попросившему text/html заголовком Accept, уходит страница: в боевом режиме с номером происшествия, в разработке — с местом в коде, цепочкой отказа, запросом и его заголовками. Слово отказа говорит на языке запроса, если каталогу дали функцию перевода. Чужой отказ на границе HTTP — таблица с числовым status — сохраняет свой статус, заголовки и опознаватель: 404 роутера остаётся 404. Готовы слой для конвейера слоёв и обработчик отказов для роутера. О внутренней поломке узнают и крюки, поставленные hook: приёмник происшествий получает её с тем же опознавателем, что и журнал. Пароли, токены, ключи, куки и строки запроса с ними вырезаются и из ответа, и из страницы, и из записи. Зависит от tnt-log (журнал и правило тайн), tnt-context (опознаватель запроса), tnt-id (азбука Крокфорда), tnt-template (разметка страницы), tnt-validate (проверка объявлений и настроек) и tnt-external (внешние зависимости и их подмена в проверках). Покрытие строк и убитых мутантов — 100 %. ]], homepage = 'https://github.com/tnt-skein/tnt-error', issues_url = 'https://github.com/tnt-skein/tnt-error/issues', maintainer = 'tnt-skein', license = 'MIT', labels = { 'tarantool', 'errors', 'http', 'rfc9457', 'problem-details' }, } dependencies = { 'lua >= 5.1', -- Опознаватель запроса на странице отказа: тот же, что журнал кладёт -- в каждую запись, — и берётся он оттуда же, из контекста файбера. 'tnt-context', -- Азбука Крокфорда для опознавателя происшествия: та же, что у ULID. 'tnt-id', -- Журнал: запись о поломке и правило тайн — список имён, secret и scrub. 'tnt-log', 'tnt-external', -- Разметка встроенной страницы отказа: она рисуется движком страниц, -- а не склеивается строками — склейка забывает экранирование. 'tnt-template', -- Проверка объявлений отказа и настроек каталога. 'tnt-validate', } build = { type = 'builtin', modules = { ['tnt.error'] = 'tnt/error.lua', ['tnt.error.accept'] = 'tnt/error/accept.lua', ['tnt.error.catalog'] = 'tnt/error/catalog.lua', ['tnt.error.failure'] = 'tnt/error/failure.lua', ['tnt.error.hook'] = 'tnt/error/hook.lua', ['tnt.error.incident'] = 'tnt/error/incident.lua', ['tnt.error.options'] = 'tnt/error/options.lua', ['tnt.error.page'] = 'tnt/error/page.lua', ['tnt.error.render'] = 'tnt/error/render.lua', ['tnt.error.secret'] = 'tnt/error/secret.lua', ['tnt.error.translation'] = 'tnt/error/translation.lua', ['tnt.error.web'] = 'tnt/error/web.lua', }, }