Skip to content

Typed error export from @chat-adapter/whatsapp (provider error codes reachable without structural parsing) #712

Description

@maxesse

Feature request: typed error export from @chat-adapter/whatsapp (and adapters generally)

Problem

@chat-adapter/whatsapp (tested against chat@4.34.0 / adapter 4.3x) surfaces Meta Graph API send failures as plain Errors whose useful payload — the Meta error code (e.g. 131047 re-engagement window closed, 190 OAuth/auth revoked) — is only reachable by structurally probing the thrown value and, in one arm, re-parsing the JSON body embedded in error.message after the "WhatsApp API error: " prefix.

Downstream consumers that need to classify failures (retry vs. don't-retry, auth-revocation handling, window-closed policy) end up maintaining a structural parser over the error's possible shapes. Ours currently checks 13 candidate locations (error, .error, .cause, .cause.error, .response, .response.data, .response.data.error, .data, .data.error, .body, .body.error, the message-embedded JSON body, and that body's .error), pinned by a regression test that drives the real built adapter against a stubbed fetch — because any adapter release can legitimately move where the code lives.

Request

Export a typed error from the adapter (or the core chat package), e.g.:

export class ChatAdapterApiError extends Error {
  provider: string        // "whatsapp"
  status?: number         // HTTP status
  code?: number | string  // provider error code, e.g. Meta's 131047 / 190
  subcode?: number
  raw?: unknown           // provider error envelope, verbatim
}

…and throw it (or attach it as cause) from postMessage/send paths. Even just a stable, documented error.cause envelope shape would eliminate the structural probing.

Why it matters beyond WhatsApp

Instagram/Messenger adapters share Meta's error envelope, so a typed export would serve every Meta-family adapter; other providers would benefit from the same contract with their own code domains.

Happy to provide our current 13-shape parser and its pinned-format regression test as a reference for what consumers are forced to do today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions