Аккуратно обрабатывайте ошибки в продакшене, чтобы не допустить тихих сбоев. Когда вызов вроде getResult() завершается неудачей, SDK выбрасывает TracioError — подкласс Error с машиночитаемым полем code.
Оберните await tracio.getResult() в try/catch, сузьте тип выброшенного значения с помощью isTracioError(), а затем разветвитесь по error.code:
import { Tracio, isTracioError, isRetryableError } from "@tracio/sdk"
const tracio = Tracio.init({ publicKey: "5ca175fc..." })
try { const result = await tracio.getResult() console.log(result.visitorId, result.bot.detected)} catch (error) { if (isTracioError(error)) { if (isRetryableError(error)) { // Transient failure (network, timeout, blocked script, upstream) — // a fresh attempt may succeed. console.warn(`Retryable TRACIO error: ${error.code}`) } else { // Terminal failure (bad config, misuse, destroyed instance) — // fix the caller; retrying the same call will not help. console.error(`Terminal TRACIO error: ${error.code} — ${error.message}`) } } else { console.error("Unexpected error:", error) }}Агент загружается асинхронно в фоне. Если загрузка завершается неудачей до того, как вы вызовете getResult(), ошибка доставляется через колбэк onError. Зарегистрируйте его сразу после init():
const tracio = Tracio.init({ publicKey: "5ca175fc..." })
tracio.onError((error) => { // Same TracioError instance you would catch from getResult(). console.warn(`TRACIO failed to initialize: ${error.code}`)})
tracio.onReady((result) => { console.log("Visitor identified:", result.visitorId)})Та же самая ошибка остаётся доступной через getResult() — вы можете использовать любой из каналов.
Каждый TracioError несёт code типа TracioErrorCode. Геттер retryable (и вспомогательная функция isRetryableError()) сообщают, может ли новая попытка оказаться успешной.
| Code | Значение | Повторяемая |
|---|---|---|
invalid_config | Конфигурация, переданная в Tracio.init(), некорректна | Нет |
multiple_keys | На одной странице использовано более одного публичного ключа | Нет |
non_browser | getResult() был выполнен вне браузера (например, на сервере) | Нет |
load_failed | Скрипт агента не удалось загрузить | Да |
blocked | Скрипт был заблокирован (блокировщик рекламы или CSP) | Да |
script_error | Загруженный скрипт выбросил ошибку при инициализации | Да |
network | Сбой сети/транспорта при обращении к API | Да |
timeout | Вызов превысил настроенный бюджет timeoutMs | Да |
server | Edge/сервер вернул ошибку вышестоящего сервиса | Да |
destroyed | Экземпляр был уничтожен (через destroy()) до вызова | Нет |
Терминальные коды (invalid_config, multiple_keys, non_browser, destroyed) указывают на проблему конфигурации, использования или жизненного цикла — исправьте вызывающий код или вызовите Tracio.init() снова. Повторяемые коды носят временный характер, и новая попытка может оказаться успешной.
Для повторяемых ошибок делайте повтор с задержкой (backoff) через новую попытку, а не повторно ожидайте тот же отклонённый промис:
import { Tracio, isRetryableError } from "@tracio/sdk"
async function identifyWithRetry(maxAttempts = 3) { let attempt = 0 while (true) { const tracio = Tracio.init({ publicKey: "5ca175fc..." }) try { return await tracio.getResult() } catch (error) { attempt++ // Tear down before retrying: init() returns the cached instance for the // same key, and getResult() caches its (rejected) promise — so a genuine // fresh attempt requires destroy() first. tracio.destroy() if (!isRetryableError(error) || attempt >= maxAttempts) throw error await new Promise((r) => setTimeout(r, 2 ** attempt * 250)) } }}