@andrey4emk/npm-app-back-b24 5.2.0 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bitrix24/b24/retry.ts +15 -5
- package/logs/logs.ts +9 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -242,7 +242,7 @@ const sent = await fetchWithTimeout("https://api.example.com/send", { method: "P
|
|
|
242
242
|
|
|
243
243
|
**Уровни логов.** Промежуточные попытки пишутся на `warn`, окончательный отказ — на `error`: исчерпание всех попыток и отмена повтора гейтом. Так один упавший вызов даёт одно сообщение в Телеграм-группу через ретранслятор вместо пяти, но при этом не теряется совсем. Логировать провал обязан сам Proxy: `errorB24()`, `Event` и `Smsgold` ошибку только возвращают вызывающему коду и в лог не пишут.
|
|
244
244
|
|
|
245
|
-
**Создающие вызовы не повторяются Proxy-слоем.** Если в вызове есть метод, создающий сущность или запускающий действие (`*.add`, `*.create`, `*.start`, `*.send`, `*.uploadfile`, `*.import`, `*.register` — в том числе среди команд `callBatch`), retry отменяется, а в лог идёт `повтор отменён`. Причина: транспортная ошибка не говорит, дошёл ли запрос до портала. Обрыв приходит и когда соединение не состоялось, и когда оно случилось после того, как портал уже принял и выполнил запрос — а повтор во втором случае создаёт вторую задачу, второй файл, второй экземпляр бизнес-процесса. Идемпотентные записи (`*.update`, `*.delete`, `*.set`) повторяются как прежде: повторное применение даёт то же состояние.
|
|
245
|
+
**Создающие вызовы не повторяются Proxy-слоем.** Если в вызове есть метод, создающий сущность или запускающий действие (`*.add`, `*.create`, `*.start`, `*.send`, `*.upload`, `*.uploadfile`, `*.import`, `*.register` — в том числе среди команд `callBatch`), retry отменяется, а в лог идёт `повтор отменён`. Причина: транспортная ошибка не говорит, дошёл ли запрос до портала. Обрыв приходит и когда соединение не состоялось, и когда оно случилось после того, как портал уже принял и выполнил запрос — а повтор во втором случае создаёт вторую задачу, второй файл, второй экземпляр бизнес-процесса. Идемпотентные записи (`*.update`, `*.delete`, `*.set`) повторяются как прежде: повторное применение даёт то же состояние. Загрузка файла в чат (`imbot.v2.File.upload`, `im.v2.File.upload`) под защитой с выпуска после 5.2.0: раньше обрыв связи повторял её до пяти раз, и в чат приходили одинаковые файлы.
|
|
246
246
|
|
|
247
247
|
Ключевое слово ищется **в любой позиции** имени, а не только в конце: `imconnector.send.messages` и `imconnector.send.status.delivery` тоже под гейтом. После ключевого слова обязателен разделитель (`.`, `?` или конец строки), поэтому `crm.deal.addcustom` и `landing.landing.addbytemplate` повторяются как прежде.
|
|
248
248
|
|
package/bitrix24/b24/retry.ts
CHANGED
|
@@ -39,7 +39,7 @@ export const NETWORK_ERROR_CODES = new Set(["NETWORK_ERROR", "REQUEST_TIMEOUT",
|
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* REST-методы B24, повтор которых создаёт дубликат сущности или запускает
|
|
42
|
-
* повторное действие: add, create, start, send, uploadfile, import, register.
|
|
42
|
+
* повторное действие: add, create, start, send, upload, uploadfile, import, register.
|
|
43
43
|
*
|
|
44
44
|
* Транспортная ошибка не говорит, дошёл ли запрос до портала: обрыв приходит
|
|
45
45
|
* и когда соединение не состоялось, и когда оно оборвалось после того, как портал уже
|
|
@@ -66,8 +66,14 @@ export const NETWORK_ERROR_CODES = new Set(["NETWORK_ERROR", "REQUEST_TIMEOUT",
|
|
|
66
66
|
* перестанет, и это осознанная плата за правило без списка исключений: потеря отметки
|
|
67
67
|
* о доставке косметическая, переписку она не ломает, а ручной список молча устаревал бы
|
|
68
68
|
* при появлении нового метода портала — ровно тот дефект, которым T-48 и был.
|
|
69
|
+
*
|
|
70
|
+
* Слово `upload` добавлено задачей T-73: `imbot.v2.File.upload` и `im.v2.File.upload`
|
|
71
|
+
* загружают файл в чат, а в перечне было только `uploadfile`, и обрыв связи давал до пяти
|
|
72
|
+
* одинаковых файлов в чате. Разделитель после слова по-прежнему обязателен, поэтому
|
|
73
|
+
* `upload` не срабатывает внутри `uploadfile` (тот ловится своим словом) и внутри
|
|
74
|
+
* имён вида `crm.deal.uploadcustom`.
|
|
69
75
|
*/
|
|
70
|
-
export const NON_IDEMPOTENT_METHOD_RE = /\.(add|create|start|send|uploadfile|import|register)(\.|\?|$)/i;
|
|
76
|
+
export const NON_IDEMPOTENT_METHOD_RE = /\.(add|create|start|send|upload|uploadfile|import|register)(\.|\?|$)/i;
|
|
71
77
|
|
|
72
78
|
/**
|
|
73
79
|
* Методы, повтор которых теряет данные, хотя сущностей не создаёт.
|
|
@@ -450,9 +456,13 @@ export async function runWithRetry<T>(fn: () => Promise<T>, label: string, block
|
|
|
450
456
|
// потеряться уже после того, как портал его выполнил. Различить нельзя,
|
|
451
457
|
// поэтому вызовы под ограничением не повторяем — лучше вернуть ошибку,
|
|
452
458
|
// чем создать дубликат или потерять зарезервированный пакет
|
|
453
|
-
// Отмена только резервирующего вызова (event.offline.get) — warn:
|
|
454
|
-
//
|
|
455
|
-
//
|
|
459
|
+
// Отмена только резервирующего вызова (event.offline.get) — warn: повтор потерю не
|
|
460
|
+
// исправит, а зависшие пакеты подбирает само приложение (b24_conector#T-97). Строки
|
|
461
|
+
// приложений о транспортном обрыве (socket hang up, ECONNRESET, таймаут) несут сетевой
|
|
462
|
+
// признак и уходят только сводкой, поэтому одиночный обрыв виден лишь в Loki — это
|
|
463
|
+
// принято сознательно. Строка об ответе без JSON («портал вернул не JSON: HTTP 200,
|
|
464
|
+
// text/html…») сетевого признака не несёт и уходит в Телеграм сразу.
|
|
465
|
+
// Отмена создающего остаётся error: сущность могла не создаться
|
|
456
466
|
if (blockReason && !proven) {
|
|
457
467
|
const level = blockReason.includes(CREATING_REASON_HEAD) ? "error" : "warn";
|
|
458
468
|
logs.add(`${label}${code}: повтор отменён, ${blockReason} — ${msg}`, level);
|
package/logs/logs.ts
CHANGED
|
@@ -78,9 +78,16 @@ const NETWORK_FAILURE_RE =
|
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Строки с сетевым признаком, которые уходят сразу и по одной: отменённое создание
|
|
81
|
-
* сущности, провал обмена токена, неизвестный статус
|
|
81
|
+
* сущности, провал обмена токена, неизвестный статус доставки, потерянное после повторов
|
|
82
|
+
* сообщение («[tg_1] Сообщение оператора не доставлено после 5 повторных попыток…: fetch failed»
|
|
83
|
+
* из b24_conector) — их разбирает человек.
|
|
84
|
+
* Фраза «не доставлено» выводит из сводки и вторую строку b24_conector:
|
|
85
|
+
* «[<ключ>] Сообщение не доставлено в Битрикс24: соединение не состоялось (id: N): getaddrinfo ENOTFOUND …»
|
|
86
|
+
* (reportSendFailure в server/api/telegram/b24MessageBuffer.ts, уровень error). Это тоже настоящая
|
|
87
|
+
* потеря сообщения, так задумано. Следствие: если портал долго недоступен, в Телеграм придёт
|
|
88
|
+
* по одному сообщению на каждое входящее сообщение клиента
|
|
82
89
|
*/
|
|
83
|
-
const NETWORK_KEEP_RE = /вызов создаёт сущности|обновление токена не удалось|статус
|
|
90
|
+
const NETWORK_KEEP_RE = /вызов создаёт сущности|обновление токена не удалось|статус неизвестен|не доставлено/;
|
|
84
91
|
|
|
85
92
|
/** Окно, за которое считаются сетевые сбои, и пауза между сводками, мс */
|
|
86
93
|
const NETWORK_WINDOW_MS = 15 * 60_000;
|