@bondi-labs/integration-sdk - v0.0.1
    Preparing search index...

    Error handling, retries, dry-run

    Trigger emits are async network calls. This guide covers how the SDK handles failures, retries, and offline development.

    Two flavors:

    Method Returns Throws? Use when
    emit(payload) void Never Best-effort observability — don't block business logic
    emitAndWait(payload) Promise<void> On any failure You need to confirm Bondi accepted the event before proceeding
    // Fire and forget — most common case
    this.contactCreated.emit({ id, email, fullName });

    // Awaiting — for transactional flows
    await this.contactCreated.emitAndWait({ id, email, fullName });

    Default recommendation: use emit(). Webhook delivery has its own retry queue inside Bondi; failing to enqueue should not break user-facing requests.

    emit() swallows errors so they never bubble into your business code. Configure a callback to log/observe them:

    import { createBondiClient } from "@bondi-labs/integration-sdk/core";

    const client = createBondiClient({
    workspaceId: process.env.BONDI_WORKSPACE_ID,
    token: process.env.BONDI_INTEGRATION_TOKEN,
    apiUrl: process.env.BONDI_API_URL,
    onEmitError: (err, eventName) => {
    logger.warn({ err, eventName }, "Bondi emit failed");
    sentryClient.captureException(err, { tags: { eventName } });
    },
    });

    For NestJS, use BondiClient.config.onEmitError after binding (less common — usually you set it via a factory in BondiModule.forRoot):

    BondiModule.forRoot({
    integration: { name: "My CRM", slug: "my-crm", category: "crm" },
    triggers: [...],
    // onEmitError: not directly supported in forRoot, but you can wrap BondiClient yourself
    })

    If you need custom error handling in NestJS, consider using emitAndWait() inside a try/catch — that gives you full control.

    The internal client retries network failures and 5xx responses up to 3 times with exponential backoff (1s, 2s, 4s). 4xx responses are NOT retried — they're treated as permanent errors (auth failures, validation rejections).

    Retry is opaque to your code: by the time emit() calls onEmitError (or emitAndWait() resolves/rejects), retries are exhausted.

    The retry config is currently not customer-configurable. If you need different behavior, file an issue.

    For local development without a real Bondi connection:

    const client = createBondiClient({
    workspaceId: process.env.BONDI_WORKSPACE_ID,
    token: process.env.BONDI_INTEGRATION_TOKEN,
    apiUrl: process.env.BONDI_API_URL,
    dryRun: true, // explicit
    });

    In dry-run mode, emit() logs the payload to console instead of making an HTTP call:

    [Bondi DryRun] contact.created { id: "1", email: "alice@example.com" }
    

    Auto dry-run: if token, apiUrl, or workspaceId is missing/empty, the client switches to dry-run automatically. This is the recommended pattern for local development — just don't set the env vars on your dev machine and emits become no-ops with logs.

    Symptom Probable cause Fix
    401 invalid_signature on Bondi side Token mismatch or stale token after rotation Re-run npx bondi init or update BONDI_INTEGRATION_TOKEN from Studio rotation
    401 expired_timestamp Clock drift (>5 min) Run NTP; ensure server time is correct
    404 on emit Slug mismatch — integration deleted or never synced npx bondi sync to register the definition
    410 Integration is deactivated Soft-deleted from Studio Re-create the integration
    429 Rate-limited (60/min per integration, 1000/hr per workspace) Throttle emits; consider batching at app level
    BondiClient not injected (NestJS) BondiModule.forRoot() not imported, or trigger class missing from triggers: [...] Add the trigger class to the module options
    • [ ] onEmitError configured to ship errors to your observability stack
    • [ ] BONDI_INTEGRATION_TOKEN stored as a secret (Vault/Secrets Manager/etc.) — not committed
    • [ ] Dev environments use dry-run (omit env vars or set dryRun: true)
    • [ ] CI runs npx bondi sync --fail-on-error --dry-run to catch broken definitions before deploy
    • [ ] Token rotation calendar reminder every 90 days