Skip to content

feat: type the error event payload (replace any)#163

Open
rodriguescarson wants to merge 1 commit into
VapiAI:mainfrom
rodriguescarson:feat/typed-error-event-payload
Open

feat: type the error event payload (replace any)#163
rodriguescarson wants to merge 1 commit into
VapiAI:mainfrom
rodriguescarson:feat/typed-error-event-payload

Conversation

@rodriguescarson

Copy link
Copy Markdown

Closes #157

Problem

The error listener is typed (error: any) in VapiEventListeners, so consumers maintain hand-rolled types and only catch contract changes at runtime. The issue asks for official, versioned types for the error event payload.

Change

Every this.emit('error', ...) call site in vapi.ts emits the same envelope, so this types it from the actual source:

  • Export the existing SerializedError interface (it keeps its [key: string]: any index signature, so provider/backend fields — e.g. a nested error.error.subscriptionLimits, Daily.co's errorMsg — remain readable by narrowing).
  • Add and export a VapiError interface: type, error: SerializedError, timestamp, plus optional stage, duration, totalDuration, and context (the fields that actually appear across the emit sites).
  • Type error: (error: VapiError) => void.

This is a typings-only change — no runtime behavior changes. It's non-breaking: the envelope is fully captured, and nested/unknown fields stay accessible through SerializedError's index signature.

Scoped to the error event as the issue requested. camera-error / local-audio-level-observer-error emit the same SerializedError envelope and could be typed the same way in a follow-up; message is a larger union left out of scope.

Verification

  • npm run build (tsc && tsc --declaration) passes. Because emit's parameter is Parameters<VapiEventListeners['error']>, tsc's excess-property check confirms VapiError matches all 10 emit('error', ...) sites (it initially failed on totalDuration/context, which are now included).
  • npm test: 6/6 pass.

🤖 Generated with Claude Code

The `error` listener was typed `(error: any)`, forcing consumers to
hand-roll types and miss contract changes until runtime (VapiAI#157).

Every `this.emit('error', ...)` site emits the same envelope, so type it:
export `SerializedError` and a new `VapiError` (`type`, `error`,
`timestamp`, plus optional `stage`/`duration`/`totalDuration`/`context`)
and use it for the `error` listener. `SerializedError` keeps its index
signature, so provider/backend fields (e.g. a nested `error.subscriptionLimits`)
are still readable by narrowing.

Verified by the build: tsc's excess-property check confirms the type matches
all 10 emit sites.

Closes VapiAI#157
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeScript types for error event payload (replace any, document nested shape)

1 participant