Ошибки и отдельный workflow обработки
Неизвестная тема P-003 уже получила ручную очередь. Это нормальный исход, а не обязательно сбой workflow. Теперь рассмотрим другую ситуацию: после преобразования карточка потеряла обязательный идентификатор. Такой результат нарушает договор процесса и должен быть заметен. Подготовим правила ошибок и схему отдельного workflow, который формирует краткое описание проблемы.
Продолжаем editorial-intake-lab; история настоящих выполнений отсутствует. В приложении приведены синтетические случаи и ожидаемые реакции. Обработчик не создан в экземпляре n8n, не связан с рабочей схемой и не отправляет уведомления. Это позволяет разобрать назначение Error Trigger без придуманного отчёта об успешной интеграции.
Собственные файлы этого шага доступны в архиве fixtures и контрактов серии, папка lesson-07. Это приложения к объяснению, а не готовый экспорт workflow.
Ожидаемое исключение и нарушение договора
Сначала разделим причины. Значение web3 имеет правильный тип, но редакция пока не назначила очередь: нужна ручная проверка направления. Пустой заголовок нарушает форму заявки: требуется уточнение входа. Потерянный идентификатор после подготовки нарушает уже обещанную связь результата с источником. Первые два случая описывают вход, третий — ошибку нашего преобразования.
Можно считать любой неподходящий вход неуспешным выполнением, но это отдельная политика проекта. Для редакционного предложения полезнее подготовить понятную запись уточнения и сохранить её видимой. Если каждая неизвестная тема вызывает техническую тревогу, обслуживающий человек перестанет отличать расширение каталога от повреждения процесса. Поэтому ручные очереди не маскируем под аварии.
| Случай | Состояние данных | Ожидаемый исход | Нужен технический разбор |
|---|---|---|---|
P-003: тема web3 |
Допустимая строка | manual_review |
Обычно нет |
| Заголовок из пробелов | Непригодная форма | input_review |
Проверить источник при повторении |
| Идентификатор исчез после подготовки | Нарушенный результат | Ошибка договора | Да |
| Внешний сервис временно не отвечает | Возможный будущий сбой | Отдельная политика повторов | Да |
Последняя строка пока не относится к работающему примеру. У нас нет внешнего сервиса, поэтому нельзя включить повтор и объявить устойчивость доказанной. Таблица показывает, где появится новая ответственность при расширении процесса. Причина ошибки должна указывать этап и нарушенное ожидание, а не ограничиваться сообщением «что-то пошло не так».
Stop And Error для неприемлемого результата
Для выбранного нарушения можно предусмотреть узел Stop And Error. Он позволяет вызвать ошибку с сообщением или объектом. В нашем проектном варианте код причины — prepared_id_lost, этап — Prepare record. Документация Stop And Error описывает эти две формы. Само добавление названия узла в контракт не означает, что такой узел уже настроен.
{
"code": "prepared_id_lost",
"stage": "Prepare record",
"expected": "non_empty_proposal_id",
"review_required": true
}
Сообщение не содержит полный текст заявки или значения HTTP-заголовков. Для определения причины они здесь не нужны. Если идентификатор уже утрачен, не стоит придумывать его в сообщении: это скроет сам дефект. В реальной истории можно было бы перейти к предыдущему узлу и сопоставить входы, но ссылки на несуществующие исполнения мы не создаём.
Также требуется учитывать выбранное поведение ошибок узла. Если схема продолжает работу после ошибки, итоговый статус может отличаться от случая остановки. Это не исправление повреждённых данных. Для нашего нарушения договором предусмотрена остановка основного результата: нельзя объявлять подборку готовой, если связь одной карточки с предложением потеряна. Более мягкий исход потребовал бы отдельного описания частичного результата.
Отдельный error workflow
Error workflow — другой workflow, связанный с основной схемой через настройки. Он начинается с Error Trigger и получает сведения о неуспешном автоматическом выполнении. Один обработчик может обслуживать несколько схем. Руководство обработки ошибок объясняет создание такой связи через Error workflow в настройках основного процесса.
В текущей документации есть существенная граница: Error Trigger не запускается из-за ошибки при ручном выполнении основного workflow. Для error workflow не требуется собственная публикация. Описание Error Trigger уточняет оба условия. Поэтому ручное нажатие запуска с намеренной ошибкой не является проверкой всей автоматической цепочки уведомления.
Наш ожидаемый обработчик состоит из Error Trigger и преобразования безопасного описания. Уведомляющего узла нет. Выход представляет объект с названием процесса, этапом, общим кодом неуспешного выполнения и признаком необходимости рассмотрения. Если позднее понадобится Slack, почта или другой канал, его подключение станет новым шагом с отдельными разрешениями и правилами хранения данных.
Сведения ошибки могут различаться. Идентификатор и URL выполнения зависят от сохранения истории; при проблеме триггера часть обычных полей отсутствует. Следовательно, преобразование должно переносить ссылку только при её наличии, а не соединять базовый адрес с неопределённым значением. В простом Safe error digest поле ссылки вообще не создаём: оно потребовалось бы отдельному внутреннему диагностическому варианту с проверенным адресом.
Практическая схема обработчика начинается с нового workflow Editorial error digest. Добавьте Error Trigger, затем Edit Fields с именем Safe error digest и соедините эти узлы. Для выходных полей выберите Manual Mapping и сохранение только заданных полей. workflow_name получает выражение {{ $json.workflow?.name ?? 'unknown_workflow' }}, stage — {{ $json.execution?.lastNodeExecuted ?? 'trigger_or_unknown' }}, Boolean review_required — фиксированное true. Поле code пока задаётся фиксированной строкой execution_failed: произвольное сообщение ошибки не разбирается как достоверный внутренний код.
У основной схемы в настройках Error workflow можно было бы выбрать Editorial error digest. Это следующий ручной шаг настройки после создания обработчика, а не провод между двумя canvas. Для нашей текущей модели связь остаётся не созданной. Если хотите отдельно исследовать проектное нарушение, предусмотрите If перед завершением карточки: Boolean {{ typeof $json.id === 'string' && $json.id.trim().length > 0 }} должен быть true. False идёт к Stop And Error с именем Preparation invariant error и Error Message prepared_id_lost; true — к дальнейшему результату. Эта проверка относится к ожидаемой форме выхода, а не заменяет первоначальную проверку заявки.
История и полезное сообщение
История Executions полезна для чтения входов и выходов конкретной попытки. Доступные записи зависят от настроек сохранения успешных, неуспешных и ручных выполнений. Настройки workflow описывают эти варианты. Пустая история сама по себе не доказывает отсутствие ошибок: нужные выполнения могли не сохраняться или уже не быть доступными.
Для настоящего процесса нужно заранее решить, какие данные сохраняются и кому они доступны. Заявки способны содержать черновые тексты или персональные сведения, хотя наши fixtures их не содержат. Сохранение всех входов навсегда не является обязательной целью отладки. Полезный журнал должен поддерживать разбор причины и соответствовать отдельным проектным требованиям к доступу и срокам хранения.
Представим два сообщения. Первое сообщает только название workflow и слово «ошибка». Второе указывает этап Prepare record, ожидание непустого идентификатора и необходимость проверки преобразования. Второе направляет человека к конкретной операции. Полный stack trace может понадобиться обслуживающему разработчику, но не должен автоматически попадать в публичное обсуждение или расширенный редакционный канал.
Не включайте автоматическую публикацию повторно подготовленной карточки в обработчик ошибки. Его задача — сделать дефект наблюдаемым, а не самостоятельно принять пропущенное редакционное решение. Для P-001 даже восстановление идентификатора не даёт одобрения статьи. Сохраняем прежнее правило: техническая пригодность и редакционная готовность являются разными состояниями.
Чтобы самостоятельно рассмотреть остановку, в отдельной учебной копии намеренно уберите id при подготовке карточки, затем выполните ручной запуск. На добавленном If ожидается false, на Stop And Error — сообщение prepared_id_lost. Это демонстрирует остановку основного workflow; связанный Error Trigger таким ручным действием не проверяется. Исследование его автоматического вызова потребовало бы отдельного изолированного сценария с автоматическим триггером и сохранением сведений выполнения.
В error-policy.json находятся три локальных случая, безопасное ожидаемое описание и ложные признаки создания связи и отправки уведомления. Проследите, почему unknown_topic остаётся ручным исходом, а потерянный идентификатор требует остановки. Следующий урок использует эти договорённости для поиска незаметной потери заявки и выбора данных для отладки.