Errors & reconnects
Handle command failures separately from connection failures. A rejected transfer usually leaves the session usable; a lost stream leaves your view stale. Neither standalone SDK automatically reconnects or refreshes tokens. The embedded app has its own connection management.
1. Command rejections (onError)
Server errors carry code, message, and optionally callId. They arrive through onError (TS)
or OnError (Go), without advancing the state sequence. Show a call-specific error beside that
call when possible; handle unknown codes by showing their message. A rejection does not by itself
require reconnecting. Check the error reference for recovery, including
display_as_forbidden, agent_not_available and warm-transfer prerequisites.
Most TS command methods return void; a failed unary send reports send_failed. Go command
methods generally return the send error. answerCall (TS) returns a promise and Answer (Go)
can return a missing-call error; media failures use the error callback. Unary data fetches reject
(TS) or return errors (Go). None of these return values proves the requested state change happened.
| Local error | SDK | Meaning |
|---|---|---|
disconnected | TS | The subscription threw a transport/stream error. A clean end is not reported. |
send_failed | TS | A unary command could not be sent. Its outcome may be uncertain. |
no_media | TS | Answer attempted with mediaFactory: null. |
mic_not_found, mic_permission_denied, mic_in_use | TS | Microphone absent, denied, or occupied. |
media_answer_failed | Both | Media negotiation failed; carries the call ID. |
media_create_failed, answer_send_failed | Go | Media creation or sending its answer failed; carries the call ID. |
2. Sequence gaps (onGap)
The cache detects a patch sequence that is not the previous sequence plus one. It still applies
the patch, then reports onGap / OnGap; the callback does not repair the view. Mark the UI stale
and obtain a fresh snapshot by opening a replacement subscription. Avoid sending actions based on
stale state. See sequence semantics and the notification caveat.
3. Disconnects & token expiry → reconnect with backoff
Use one recovery owner per client:
- Coalesce disconnect/gap signals into one recovery attempt. Cancel it when the user signs out.
- Mark the view stale, detach rendering, and close the old client before replacing it.
- Wait with capped exponential backoff and jitter, for example 0.5s, 1s, 2s up to 30s.
- Obtain a valid token through your login layer; stop retrying if a new interactive login is required.
- Create a client, attach callbacks, and register. Restore external-phone routing if applicable.
- Reset backoff only after observing usable state from the new connection, not when TS
connect()returns.
Do not blindly replay a failed dial, SMS, transfer or recording command: the server may have accepted it before the connection failed. Inspect the recovered state and reconcile the action first.
Audio recovery is limited. Closing either client closes media. Go also closes media when its
receive loop ends; TS does not close it merely because Subscribe throws. The server may preserve
call control across a short disconnect, but that is not a promise of uninterrupted audio. Neither
standalone SDK automatically negotiates a new leg for an already in-progress call. Reconnect when
idle where possible, and show the audio interruption if a mid-call recovery is unavoidable.
Showing a connection indicator
subscribe / Subscribe immediately calls your renderer with the current cache, which can be
empty before any network reply. That first callback is not proof of connection. Both SDKs return
cloned state; snapshots expose no separate public "connected" flag.
TS reports a thrown stream failure as disconnected; a clean stream end is silent. Go's receive
loop ends without a disconnect callback. A failed send indicates a problem, but a successful send
doesn't prove the subscription is alive. An idle agent may produce no state patches, and transport
heartbeats do not call renderers: silence alone is not a reliable disconnect detector.
Use application-level health checks appropriate to the deployment and label uncertainty honestly. Don't display an unconditional "Connected" just because construction or subscription returned.
Checklist
Wire command and media errors, treat gaps as stale state, allow only one recovery attempt, renew credentials when needed, and release the old client. Verify call control and audible media separately.
See also
Authentication owns token policy; Troubleshooting starts from symptoms; TypeScript vs Go compares lifecycle defaults.