feat: type the error event payload (replace any)#163
Open
rodriguescarson wants to merge 1 commit into
Open
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #157
Problem
The
errorlistener is typed(error: any)inVapiEventListeners, so consumers maintain hand-rolled types and only catch contract changes at runtime. The issue asks for official, versioned types for theerrorevent payload.Change
Every
this.emit('error', ...)call site invapi.tsemits the same envelope, so this types it from the actual source:SerializedErrorinterface (it keeps its[key: string]: anyindex signature, so provider/backend fields — e.g. a nestederror.error.subscriptionLimits, Daily.co'serrorMsg— remain readable by narrowing).VapiErrorinterface:type,error: SerializedError,timestamp, plus optionalstage,duration,totalDuration, andcontext(the fields that actually appear across the emit sites).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
errorevent as the issue requested.camera-error/local-audio-level-observer-erroremit the sameSerializedErrorenvelope and could be typed the same way in a follow-up;messageis a larger union left out of scope.Verification
npm run build(tsc && tsc --declaration) passes. Becauseemit's parameter isParameters<VapiEventListeners['error']>, tsc's excess-property check confirmsVapiErrormatches all 10emit('error', ...)sites (it initially failed ontotalDuration/context, which are now included).npm test: 6/6 pass.🤖 Generated with Claude Code