Skip to content

Errors

Structured errors with automatic HTTP status mapping.

Throwing errors

ts
import { CooperError } from "cooper";

throw new CooperError("NOT_FOUND", "User not found");
throw new CooperError("UNAUTHORIZED", "Token expired");
throw new CooperError("PERMISSION_DENIED", "Admins only");
throw new CooperError("RATE_LIMITED", "Slow down");
throw new CooperError("INVALID_ARGUMENT", "Email is malformed");
throw new CooperError("INTERNAL", "Unexpected failure");

Error codes → HTTP status

CodeHTTP Status
NOT_FOUND404
UNAUTHORIZED401
PERMISSION_DENIED403
RATE_LIMITED429
INVALID_ARGUMENT400
VALIDATION_FAILED422
INTERNAL500

Client response

Every error returns the same shape:

json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "User not found"
  }
}

Rate limiting and Retry-After

When a RATE_LIMITED error is thrown, Cooper automatically includes a Retry-After header in the HTTP response. You can specify the delay (in seconds) using the retryAfter field:

ts
throw new CooperError("RATE_LIMITED", "Slow down", { retryAfter: 30 });

This produces:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
json
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Slow down",
    "retryAfter": 30
  }
}

If retryAfter is omitted, Cooper defaults to 60 seconds.

Apache-2.0 Licensed