Надёжность
Политика ретраев
Заголовок раздела «Политика ретраев»Одна попытка плюс три ретрая по умолчанию; количество меняет --retries.
| Ответ | Что делает |
|---|---|
200 с ok: true |
доставлено |
200 с ok: false |
ретрай; description от Telegram сохраняется как ошибка |
429 |
ретрай после запрошенной сервером задержки |
5xx |
ретрай с экспоненциальным backoff |
| сетевой сбой, таймаут, DNS | ретрай с backoff, в отчёте HTTP 0 |
любой другой 4xx |
не ретраится |
4xx терминален намеренно. Отозванный токен, чат, из которого бота выгнали, или сообщение,
которое Telegram не может распарсить, будут отвечать одинаково сколько угодно; ретраи лишь
оттягивают момент, когда ты увидишь настоящую проблему.
Backoff
Заголовок раздела «Backoff»1 с, 2 с, 4 с плюс до 50% джиттера.
Джиттер тут не украшение. Когда флот job’ов пишет в один чат и упирается в лимит одновременно, фиксированное расписание заставляет их всех ретраить в одну и ту же секунду и снова вызывать лимит. Разброс — это разница между «восстановились» и «раскачали».
Лимиты частоты
Заголовок раздела «Лимиты частоты»На 429 notiflow ждёт parameters.retry_after из тела; если его нет — заголовок
Retry-After; если нет и его — одну секунду. Прокси и self-hosted Bot API обычно шлют
заголовок, а не поле, поэтому читаются оба.
Задержка ограничена --max-retry-after (по умолчанию 60 с). Telegram иногда просит минуты,
а шаг workflow, который столько простоял, обычно хуже пропущенного уведомления.
Таймауты
Заголовок раздела «Таймауты»--connect-timeout (5 с) ограничивает TCP- и TLS-хендшейк, --timeout (15 с) — весь
запрос. Превышение любого считается сетевым сбоем и идёт по пути backoff.
Сбой и результат job
Заголовок раздела «Сбой и результат job»По умолчанию неудачное уведомление выходит с 0. Результат сборки — то, на что люди реально реагируют, и затирать его из-за плохой минуты у Telegram означает ухудшить сигнал, а не улучшить.
fail_on_error: true (или --fail-on-error) переворачивает это, когда доставка
действительно часть контракта: код выхода становится 1, а причина попадает в выход error.
Exit-коды
Заголовок раздела «Exit-коды»| Code | Name | Meaning |
|---|---|---|
| 0 | OK |
Message delivered, or skipped by notify_on, or fail_on_error=false |
| 1 | SEND_FAILED |
Telegram never accepted the message and fail_on_error=true |
| 2 | USAGE |
Command-line parsing failed (emitted by clap) |
| 10 | MISSING_REQUIRED_INPUT |
bot_token, chat_id or status is empty |
| 11 | INVALID_CHAT_ID |
chat_id is not an integer or @username (a comma is rejected in v2) |
| 12 | INVALID_STATUS |
status is not success |
| 13 | INVALID_PARSE_MODE |
parse_mode is not MarkdownV2 |
| 14 | INVALID_NOTIFY_ON |
notify_on lists a value outside the status set |
| 15 | INVALID_THREAD_ID |
message_thread_id is not a non-negative integer |
| 16 | INVALID_EDIT_MESSAGE_ID |
edit_message_id is not a positive integer |
| 17 | CONFIG_ERROR |
Config file unreadable, malformed, or the profile does not exist |
| 18 | INVALID_ARGUMENT |
Argument is well-formed but unusable (bad api_base, zero timeout) |
| 20 | RESERVED |
v1 UNSUPPORTED_BASH — never emitted by v2 |
| 22 | RESERVED |
v1 MISSING_DEPENDENCY — never emitted by v2 |
| 30 | IO_ERROR |
Reading stdin or a message file failed, or an output file is not writable |
Коды 10–16 унаследованы от notiflow v1 дословно, поэтому workflow, который на них
ветвится, переживает апгрейд. 20 и 22 принадлежали bash-рантайму — у статического бинаря
нет ни bash, который мог бы оказаться старым, ни curl, который мог бы отсутствовать, —
и зарезервированы навсегда, а не переиспользованы.
Как разбираться со сбоем
Заголовок раздела «Как разбираться со сбоем»Начни с выхода error или с JSON-отчёта: если Telegram назвал причину, там она дословно.
| Симптом | Обычная причина |
|---|---|
401 Unauthorized |
неверный или отозванный токен — проверь notiflow whoami |
400 Bad Request: chat not found |
неверный chat_id либо бота никогда не добавляли в чат |
403 Forbidden |
бот в чате, но писать не может; для канала нужен админ |
400 ... can't parse entities |
дословный message с разметкой — см. Parse modes |
429 на каждой попытке |
слишком много сообщений в один чат; подними --max-retry-after или шли реже |
| HTTP 0 | до сервера не дошли — сеть, DNS или прокси на раннере |
-v добавляет в stderr решения о ретраях, -vv — отладочные детали. Ни то, ни другое не
может напечатать токен: всё, что notiflow пишет, проходит через фильтр редактирования.