Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt

Use this file to discover all available pages before exploring further.

Error Handling

The SDK exposes error-related behavior through three main channels:
EventPurposeRecommended use
telnyx.errorFatal or blocking SDK errorsShow actionable errors, retry, re-authenticate
telnyx.warningNon-fatal quality, connectivity, and token warningsShow degraded-state UI, collect telemetry
telnyx.notificationCall lifecycle updates and compatibility notificationsDrive call UI and hangup handling
Use telnyx.ready to know when the client is authenticated and the gateway is ready. Do not treat readiness as a notification case.

Structured Errors (telnyx.error)

telnyx.error is the primary error surface. Listen for it to handle authentication failures, media errors, and connection issues.

Imports

import {
  SwEvent,
  TelnyxError,
  TELNYX_ERROR_CODES,
  isMediaRecoveryErrorEvent,
} from '@telnyx/webrtc';

Basic example

client.on(SwEvent.Error, (event) => {
  if (isMediaRecoveryErrorEvent(event)) {
    openPermissionsDialog({
      deadline: event.retryDeadline,
      onRetry: () => event.resume(),
      onCancel: () => event.reject(),
    });
    return;
  }

  if (!(event.error instanceof TelnyxError)) {
    showErrorMessage('An unknown SDK error occurred.');
    return;
  }

  switch (event.error.code) {
    case TELNYX_ERROR_CODES.NETWORK_OFFLINE:
      showErrorMessage('You appear to be offline.');
      break;
    case TELNYX_ERROR_CODES.AUTHENTICATION_REQUIRED:
      showErrorMessage('Session expired. Please authenticate again.');
      break;
    default:
      showErrorMessage(event.error.message);
  }
});

Media permission recovery

When mediaPermissionsRecovery.enabled is configured and getUserMedia() fails while answering a call, the error event includes recoverable: true with resume() and reject() callbacks:
const client = new TelnyxRTC({
  login_token: jwt,
  mediaPermissionsRecovery: {
    enabled: true,
    timeout: 10000,
  },
});

client.on(SwEvent.Error, (event) => {
  if (isMediaRecoveryErrorEvent(event)) {
    // Show a dialog asking the user to grant microphone permission
    // event.retryDeadline is the timestamp by which they must act
    showPermissionDialog({
      onGrant: () => event.resume(),
      onDismiss: () => event.reject(),
    });
  }
});

Error Code Reference

SDP errors

CodeNameTypical trigger
40001SDP_CREATE_OFFER_FAILEDcreateOffer() failed
40002SDP_CREATE_ANSWER_FAILEDcreateAnswer() failed
40003SDP_SET_LOCAL_DESCRIPTION_FAILEDsetLocalDescription() failed
40004SDP_SET_REMOTE_DESCRIPTION_FAILEDsetRemoteDescription() failed
40005SDP_SEND_FAILEDInvite/answer signaling could not be sent

Media errors

CodeNameTypical trigger
42001MEDIA_MICROPHONE_PERMISSION_DENIEDBrowser or OS denied microphone permission
42002MEDIA_DEVICE_NOT_FOUNDMissing/disconnected device or invalid deviceId
42003MEDIA_GET_USER_MEDIA_FAILEDgetUserMedia() failed for another reason

Call-control errors

CodeNameTypical trigger
44001HOLD_FAILEDHold request failed
44002INVALID_CALL_PARAMETERSRequired call params were missing or invalid
44003BYE_SEND_FAILEDBYE could not be sent
44004SUBSCRIBE_FAILEDVerto subscribe failed

WebSocket and transport errors

CodeNameTypical trigger
45001WEBSOCKET_CONNECTION_FAILEDWebSocket connection failed
45002WEBSOCKET_ERRORBrowser ws.onerror fired
45003RECONNECTION_EXHAUSTEDReconnect attempts exhausted
45004GATEWAY_FAILEDGateway reported FAILED or FAIL_WAIT

Authentication and session errors

CodeNameTypical trigger
46001LOGIN_FAILEDLogin rejected or never reached ready state
46002INVALID_CREDENTIALSClient-side login validation failed
46003AUTHENTICATION_REQUIREDRequest sent before auth or after auth was lost
48001NETWORK_OFFLINEBrowser offline event fired
49001UNEXPECTED_ERRORUnclassified failure during peer/call setup

Structured Warnings (telnyx.warning)

Warnings are not fatal. They describe degraded behavior, quality issues, or situations that may need user action before the session breaks.

Basic example

import { SwEvent, TELNYX_WARNING_CODES } from '@telnyx/webrtc';

client.on(SwEvent.Warning, ({ warning, callId }) => {
  if (warning.code === TELNYX_WARNING_CODES.TOKEN_EXPIRING_SOON) {
    refreshToken();
    return;
  }

  if (warning.code === TELNYX_WARNING_CODES.PEER_CONNECTION_FAILED) {
    showWarningBanner('Call is reconnecting');
    return;
  }

  console.warn(`[${warning.code}] ${warning.name}: ${warning.message}`);
});

Warning code reference

Network quality warnings

CodeNameTypical trigger
31001HIGH_RTTRTT stayed above threshold
31002HIGH_JITTERJitter stayed above threshold
31003HIGH_PACKET_LOSSPacket loss stayed above threshold
31004LOW_MOSMOS stayed below threshold

Data-flow warnings

CodeNameTypical trigger
32001LOW_BYTES_RECEIVEDRemote audio bytes stopped increasing
32002LOW_BYTES_SENTLocal audio bytes stopped increasing

Connectivity warnings

CodeNameTypical trigger
33001ICE_CONNECTIVITY_LOSTICE connection state became disconnected
33002ICE_GATHERING_TIMEOUTICE gathering safety timeout fired
33003ICE_GATHERING_EMPTYNo candidates were collected
33004PEER_CONNECTION_FAILEDPeer connection state became failed
33005ONLY_HOST_ICE_CANDIDATESSDP contained only host ICE candidates

Authentication and session warnings

CodeNameTypical trigger
34001TOKEN_EXPIRING_SOONJWT expires within 120 seconds
35001SESSION_NOT_REATTACHEDActive call lost after reconnect

Call Termination Data

When a call reaches hangup, inspect these fields on the Call object:
FieldTypeMeaning
causestringHigh-level cause (USER_BUSY, CALL_REJECTED, etc.)
causeCodenumberNumeric cause code
sipCodenumberSIP response code when available
sipReasonstringSIP reason phrase when available
Common causes:
CauseMeaning
NORMAL_CLEARINGExpected call completion
USER_BUSYRemote party was busy
CALL_REJECTEDRemote party rejected the call
NO_ANSWERCall timed out unanswered
UNALLOCATED_NUMBERDialed number is invalid or does not exist

Socket Events

telnyx.socket.close

Delivers the browser CloseEvent. During a forced safety cleanup, the SDK emits a synthetic abnormal close with code: 1006 and wasClean: false. Useful close codes:
CodeMeaning
1000Normal closure
1001Going away
1006Abnormal closure
1011Internal error

telnyx.socket.error

Delivers { error: ErrorEvent, sessionId: string }. Browsers expose very little information for WebSocket errors. The SDK also emits telnyx.error with code 45002 (WEBSOCKET_ERROR) when ws.onerror fires.

Connection State Helpers

The browser session exposes WebSocket state helpers on client.connection:
GetterMeaning
client.connection.connectedWebSocket is in OPEN
client.connection.isAliveCONNECTING or OPEN
client.connection.isDeadCLOSING or CLOSED
Example:
const placeCall = (destinationNumber) => {
  if (!client.connection.connected) {
    showErrorMessage('Still connecting to Telnyx. Please try again shortly.');
    return;
  }

  client.newCall({ destinationNumber });
};

Reconnection Behavior

On telnyx.socket.close or telnyx.socket.error, the SDK clears subscriptions and resets gateway readiness state. If autoReconnect is enabled, the browser session schedules connect() after reconnectDelay (1000ms).

Gateway retry behavior

  • UNREGED / NOREG: Up to 5 registration retries, each delayed 2-6 seconds randomly. After that, LOGIN_FAILED (46001).
  • FAILED / FAIL_WAIT: GATEWAY_FAILED (45004) emitted on first detection. Up to 5 retries with 2-6 second random delay before RECONNECTION_EXHAUSTED (45003).

Keeping media alive

If keepConnectionAliveOnSocketClose is true, the SDK preserves active peer connections while signaling reconnects. Recovery can create a new Call object with recoveredCallId.

See Also