Files
2026-05-27 23:29:53 +01:00

2.6 KiB

client/classify — HTTP status + Slack-error classifier

Purpose

classify.ts exports two pure mapping functions that fold transport-level failure signals into the stable SLACK_CODES registry. classifyHttpStatus partitions every observed HTTP status code into one of AUTH_ERROR, CHANNEL_NOT_FOUND, TIMEOUT, RATE_LIMITED, or the catch-all API_ERROR. classifySlackError does the same for Slack's JSON-level error strings (invalid_auth, channel_not_found, team_not_found, etc.). Centralising the classification keeps the API client and the webhook client in lock-step and gives downstream retry wrappers a single source of truth for what the package considers a retryable failure.

Features

  • Total HTTP-status partition — every numeric status maps to exactly one code.
  • Total Slack-error partition — every JSON error string maps to exactly one code, with regex matchers grouping family members (is_archived/not_in_channel count as CHANNEL_NOT_FOUND).
  • Pure functions — no side effects, no module-scope state, safe to tree-shake.
  • Literal-typed return — SlackErrorCode discriminated union is preserved.

Usage: Basic

import {
    classifyHttpStatus,
    classifySlackError,
} from "@suaveplan/slack-client/client/classify";

const fromStatus = classifyHttpStatus(429);
// "SLACK.RATE_LIMITED"

const fromBody = classifySlackError("invalid_auth");
// "SLACK.AUTH_ERROR"

Usage: Advanced

import {
    classifyHttpStatus,
    classifySlackError,
} from "@suaveplan/slack-client/client/classify";
import { SLACK_CODES } from "@suaveplan/slack-client/error-codes";

function isRetryable(code: ReturnType<typeof classifyHttpStatus>): boolean {
    return (
        code === SLACK_CODES.RATE_LIMITED ||
        code === SLACK_CODES.TIMEOUT ||
        code === SLACK_CODES.API_ERROR
    );
}

const retry = isRetryable(classifyHttpStatus(503));
// true

API Reference

  • classifyHttpStatus(status: number): SlackErrorCode
  • classifySlackError(slackError: string): SlackErrorCode

Implementation Notes

The Slack-error matchers use case-insensitive regular expressions because Slack's documentation is inconsistent on casing and the API has historically returned both invalid_auth and Invalid_Auth in different surfaces. The order of the checks is important — invalid_auth must match before any not_* matcher because not_authed is an auth error, not a channel error. The HTTP-status partition deliberately uses === comparisons rather than range checks so that adding a new status (e.g. 451) requires an explicit decision rather than silently joining the catch-all bucket.