Error Handling

Handle rate limits, unsupported features, and other errors from adapters.

The SDK provides typed error classes for common failure scenarios. All errors are importable from the chat package.

import { ChatError, RateLimitError, NotImplementedError, LockError } from "chat";

Error types

ChatError

Base error class for all SDK errors. Every error below extends ChatError. The code property carries a machine-readable identifier you can branch on:

CodeThrown byMeaning
NOT_SUPPORTEDbot.openDM, bot.getUserThe resolved adapter doesn't implement this method
INVALID_THREAD_IDbot.thread, internal routingThread ID does not match the adapter:channel:thread shape
INVALID_CHANNEL_IDbot.channelChannel ID does not match the adapter:channel shape
ADAPTER_NOT_FOUNDbot.thread, bot.channelThread/channel ID references an adapter that wasn't registered on this Chat instance
AMBIGUOUS_USER_IDbot.getUser, bot.openDMNumeric user ID could match more than one registered adapter (Discord/Telegram/GitHub)
UNKNOWN_USER_ID_FORMATbot.getUser, bot.openDMThe userId doesn't match any platform's known ID format
RATE_LIMITEDAny platform callPlatform returned 429; see RateLimitError below
NOT_IMPLEMENTEDAny platform callThe adapter doesn't implement this feature; see NotImplementedError below
LOCK_FAILEDInbound message routingDistributed lock was busy; see LockError below

Prop

Type

RateLimitError

Thrown when a platform API returns a 429 response. The retryAfterMs property tells you how long to wait before retrying.

lib/bot.ts
import { RateLimitError } from "chat";

try {
  await thread.post("Hello!");
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`Rate limited, retry after ${error.retryAfterMs}ms`);
  }
}

Prop

Type

NotImplementedError

Thrown when you call a feature that a platform doesn't support. For example, calling addReaction() on Teams or schedule() on adapters without native scheduling support.

lib/bot.ts
import { NotImplementedError } from "chat";

try {
  await thread.addReaction(emoji.thumbs_up);
} catch (error) {
  if (error instanceof NotImplementedError) {
    console.log(`Feature not supported: ${error.feature}`);
  }
}

Prop

Type

See the feature matrix for which features are supported on each platform.

LockError

Thrown when the SDK fails to acquire a distributed lock on a thread (used to prevent concurrent processing of messages in the same thread). You can control this behavior with the onLockConflict option — set it to 'force' to release the existing lock instead of throwing.

Prop

Type

Adapter errors

Adapters also throw specialized errors from the @chat-adapter/shared package:

ErrorCodeDescription
AdapterRateLimitErrorRATE_LIMITEDPlatform rate limit hit, includes retryAfter in seconds
AuthenticationErrorAUTH_FAILEDInvalid or expired credentials
ResourceNotFoundErrorNOT_FOUNDRequested resource (channel, message) doesn't exist
PermissionErrorPERMISSION_DENIEDBot lacks required permissions/scopes
ValidationErrorVALIDATION_ERRORInvalid input data (e.g. message too long)
NetworkErrorNETWORK_ERRORConnectivity issue with platform API

Catching errors

Use instanceof to handle specific error types:

lib/bot.ts
import { RateLimitError, NotImplementedError } from "chat";

bot.onNewMention(async (thread, message) => {
  try {
    await thread.post("Processing...");
    await thread.addReaction(emoji.eyes);
  } catch (error) {
    if (error instanceof RateLimitError) {
      // Wait and retry
      await new Promise((r) => setTimeout(r, error.retryAfterMs ?? 5000));
      await thread.post("Processing...");
    } else if (error instanceof NotImplementedError) {
      // Skip unsupported features gracefully
    } else {
      throw error;
    }
  }
});

On this page

GitHubEdit this page on GitHub