spearkit
Guides

Discord API errors

discord.js reports REST failures as DiscordAPIError with a numeric code (10008 "Unknown Message", 50013 "Missing Permissions", 50007 "Cannot send DMs to this user", …). Catching…

Recognise and recover

isDiscordError(err, code?) narrows the throw and optionally matches a code (or a list). Perfect for "ignore this one, re-throw the rest":

import { DiscordErrorCode, isDiscordError } from "spearkit";

try {
  await message.delete();
} catch (err) {
  if (isDiscordError(err, DiscordErrorCode.UnknownMessage)) return; // already gone
  throw err;
}
// match any of several codes
if (isDiscordError(err, [DiscordErrorCode.UnknownChannel, DiscordErrorCode.MissingAccess])) {
  return;
}

Friendly messages

explainDiscordError(err) returns an end-user-appropriate sentence for a recognised failure, or null otherwise (fall back to a generic message + log):

import { explainDiscordError } from "spearkit";

catch (err) {
  await ctx.error(explainDiscordError(err) ?? "Something went wrong.");
}

spearkit already routes its own command/context-menu errors through explainDiscordError, so a handler that throws Missing Permissions shows the user "I'm missing the permissions needed to do that." instead of a generic error.

Named codes

DiscordErrorCode is a curated map of the codes bots actually hit:

NameCodeWhen
UnknownChannel10003Channel gone/invisible
UnknownMessage10008Message deleted
UnknownMember10007Member left
UnknownInteraction10062Token expired (the 3s window)
MissingAccess50001No access to the resource
CannotSendMessagesToThisUser50007DMs closed / blocked
MissingPermissions50013Missing a permission
InteractionHasAlreadyBeenAcknowledged40060Double-acked

(See the type for the full set — it mirrors discord.js' RESTJSONErrorCodes.)

Transport & rate-limit errors

  • isHTTPError(err) — a transport-level HTTPError (timeout, 5xx, aborted): an HTTP status with no Discord JSON code.
  • isRateLimitError(err) — a DiscordAPIError with HTTP status 429. explainDiscordError handles this case first, returning a "try again in a moment" message.

On this page