@jaypie/errors
Prerequisites: npm install jaypie or npm install @jaypie/errors
Overview
Section titled “Overview”@jaypie/errors provides typed error classes that map to HTTP status codes and format as JSON:API errors.
Installation
Section titled “Installation”npm install jaypie# ornpm install @jaypie/errorsQuick Reference
Section titled “Quick Reference”Error Classes
Section titled “Error Classes”| Class | Status | Use Case |
|---|---|---|
BadRequestError |
400 | Invalid input |
UnauthorizedError |
401 | Authentication required |
ForbiddenError |
403 | Permission denied |
NotFoundError |
404 | Resource not found |
MethodNotAllowedError |
405 | Wrong HTTP method |
GoneError |
410 | Resource deleted |
TeapotError |
418 | Easter egg |
TooManyRequestsError |
429 | Rate limited |
InternalError |
500 | Server error |
ConfigurationError |
500 | Missing config |
NotImplementedError |
400 | Feature not built |
BadGatewayError |
502 | Upstream error |
UnavailableError |
503 | Service down |
GatewayTimeoutError |
504 | Upstream timeout |
RejectedError |
403 | Request rejected |
Utilities
Section titled “Utilities”| Export | Purpose |
|---|---|
isJaypieError |
Type guard for Jaypie errors |
jaypieErrorFromStatus |
Create error from status code |
Throwing Errors
Section titled “Throwing Errors”Both syntaxes work:
import { BadRequestError, NotFoundError } from "jaypie";
// Function call (preferred)throw BadRequestError("Missing required field");
// Constructorthrow new BadRequestError("Missing required field");Error Properties
Section titled “Error Properties”const error = NotFoundError("User not found");
error.status; // 404error.name; // "NotFoundError"error.message; // "User not found"error.isJaypie; // trueJSON:API Body
Section titled “JSON:API Body”const error = BadRequestError("Invalid email");error.body();Returns:
{ "errors": [ { "status": 400, "title": "Bad Request", "detail": "Invalid email" } ]}Type Guard
Section titled “Type Guard”import { isJaypieError, InternalError } from "jaypie";
try { await riskyOperation();} catch (error) { if (isJaypieError(error)) { return res.status(error.status).json(error.body()); } throw InternalError();}From Status Code
Section titled “From Status Code”import { jaypieErrorFromStatus } from "jaypie";
const error = jaypieErrorFromStatus(404, "Not found");// Returns NotFoundErrorError Selection Guide
Section titled “Error Selection Guide”Client Errors (4xx)
Section titled “Client Errors (4xx)”| Scenario | Error |
|---|---|
| Missing required field | BadRequestError |
| Invalid format | BadRequestError |
| No auth token | UnauthorizedError |
| Invalid auth | UnauthorizedError |
| No permission | ForbiddenError |
| Resource missing | NotFoundError |
| Wrong HTTP method | MethodNotAllowedError |
| Resource deleted | GoneError |
| Rate limited | TooManyRequestsError |
Server Errors (5xx)
Section titled “Server Errors (5xx)”| Scenario | Error |
|---|---|
| Missing env var | ConfigurationError |
| External API failed | BadGatewayError |
| External API timeout | GatewayTimeoutError |
| Maintenance mode | UnavailableError |
| Unexpected state | InternalError |
Examples
Section titled “Examples”Validation
Section titled “Validation”import { BadRequestError } from "jaypie";
function validateEmail(email) { if (!email) { throw BadRequestError("Email is required"); } if (!email.includes("@")) { throw BadRequestError("Invalid email format"); }}Resource Not Found
Section titled “Resource Not Found”import { NotFoundError } from "jaypie";
async function getUser(id) { const user = await db.users.findById(id); if (!user) { throw NotFoundError("User not found"); } return user;}External Service
Section titled “External Service”import { BadGatewayError, log } from "jaypie";
async function callPaymentService(data) { try { return await paymentApi.charge(data); } catch (error) { log.error("Payment service failed"); log.var({ error: error.message }); throw BadGatewayError(); }}Configuration
Section titled “Configuration”import { ConfigurationError } from "jaypie";
function getDbUri() { const uri = process.env.MONGODB_URI; if (!uri) { throw ConfigurationError("MONGODB_URI not configured"); } return uri;}Testing
Section titled “Testing”import { matchers } from "@jaypie/testkit";expect.extend(matchers);
it("throws BadRequestError for invalid input", () => { expect(() => validateEmail(null)).toThrowBadRequestError();});
it("throws any Jaypie error", () => { expect(() => riskyOperation()).toThrowJaypieError();});Available Matchers
Section titled “Available Matchers”toThrowJaypieError()toThrowBadRequestError()toThrowUnauthorizedError()toThrowForbiddenError()toThrowNotFoundError()toThrowInternalError()toThrowConfigurationError()toThrowBadGatewayError()toThrowUnavailableError()
Related
Section titled “Related”- Error Handling - Patterns and best practices
- Handler Lifecycle - Automatic error formatting
- Testing - Testing error conditions