Files
smartserve/ts/core/smartserve.errors.ts
2025-11-29 15:24:00 +00:00

130 lines
3.6 KiB
TypeScript

/**
* Custom error classes for @push.rocks/smartserve
*/
/**
* HTTP error with status code
* Thrown from handlers to return specific HTTP responses
*/
export class HttpError extends Error {
public readonly status: number;
public readonly details?: Record<string, unknown>;
constructor(
status: number,
message: string,
details?: Record<string, unknown>
) {
super(message);
this.name = 'HttpError';
this.status = status;
this.details = details;
}
/**
* Convert to HTTP Response
*/
toResponse(): Response {
return new Response(
JSON.stringify({
error: this.message,
status: this.status,
...(this.details ? { details: this.details } : {}),
}),
{
status: this.status,
headers: { 'Content-Type': 'application/json' },
}
);
}
// Common HTTP errors as static factory methods
static badRequest(message = 'Bad Request', details?: Record<string, unknown>): HttpError {
return new HttpError(400, message, details);
}
static unauthorized(message = 'Unauthorized', details?: Record<string, unknown>): HttpError {
return new HttpError(401, message, details);
}
static forbidden(message = 'Forbidden', details?: Record<string, unknown>): HttpError {
return new HttpError(403, message, details);
}
static notFound(message = 'Not Found', details?: Record<string, unknown>): HttpError {
return new HttpError(404, message, details);
}
static methodNotAllowed(message = 'Method Not Allowed', details?: Record<string, unknown>): HttpError {
return new HttpError(405, message, details);
}
static conflict(message = 'Conflict', details?: Record<string, unknown>): HttpError {
return new HttpError(409, message, details);
}
static unprocessableEntity(message = 'Unprocessable Entity', details?: Record<string, unknown>): HttpError {
return new HttpError(422, message, details);
}
static tooManyRequests(message = 'Too Many Requests', details?: Record<string, unknown>): HttpError {
return new HttpError(429, message, details);
}
static internalServerError(message = 'Internal Server Error', details?: Record<string, unknown>): HttpError {
return new HttpError(500, message, details);
}
static notImplemented(message = 'Not Implemented', details?: Record<string, unknown>): HttpError {
return new HttpError(501, message, details);
}
static badGateway(message = 'Bad Gateway', details?: Record<string, unknown>): HttpError {
return new HttpError(502, message, details);
}
static serviceUnavailable(message = 'Service Unavailable', details?: Record<string, unknown>): HttpError {
return new HttpError(503, message, details);
}
}
/**
* Error thrown when route is not found
*/
export class RouteNotFoundError extends HttpError {
constructor(path: string, method: string) {
super(404, `Route not found: ${method} ${path}`, { path, method });
this.name = 'RouteNotFoundError';
}
}
/**
* Error thrown when adapter is not supported
*/
export class UnsupportedRuntimeError extends Error {
constructor(runtime: string) {
super(`Unsupported runtime: ${runtime}`);
this.name = 'UnsupportedRuntimeError';
}
}
/**
* Error thrown when server is already running
*/
export class ServerAlreadyRunningError extends Error {
constructor() {
super('Server is already running');
this.name = 'ServerAlreadyRunningError';
}
}
/**
* Error thrown when server is not running
*/
export class ServerNotRunningError extends Error {
constructor() {
super('Server is not running');
this.name = 'ServerNotRunningError';
}
}