@voilajsx/appkit
Version:
Minimal and framework agnostic Node.js toolkit designed for AI agentic backend development
140 lines • 6.83 kB
TypeScript
/**
* Core error class with semantic HTTP status codes and middleware
* @module @voilajsx/appkit/error
* @file src/error/error.ts
*
* @llm-rule WHEN: Building apps that need semantic HTTP error handling
* @llm-rule AVOID: Using directly - always get instance via errorClass.get()
* @llm-rule NOTE: Provides semantic error creation (badRequest, unauthorized) and Express middleware
*/
import type { ErrorConfig } from './defaults.js';
export interface AppError extends Error {
statusCode: number;
type: string;
}
export interface ExpressRequest {
[key: string]: any;
}
export interface ExpressResponse {
status: (code: number) => ExpressResponse;
json: (data: any) => void;
}
export interface ExpressNextFunction {
(error?: any): void;
}
export type ExpressErrorHandler = (error: AppError, req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
export type AsyncRouteHandler = (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => Promise<any>;
export interface ErrorHandlerOptions {
showStack?: boolean;
logErrors?: boolean;
}
/**
* Error class with semantic HTTP status codes and middleware functionality
*/
export declare class ErrorClass {
config: ErrorConfig;
constructor(config: ErrorConfig);
/**
* Creates a 400 Bad Request error
* @llm-rule WHEN: Client sends invalid input data (missing fields, wrong format)
* @llm-rule AVOID: Using for server-side validation errors - use conflict() instead
* @llm-rule NOTE: EXAMPLES: missing email, invalid JSON, malformed request body
* @llm-rule NOTE: PATTERN: if (!req.body.email) throw error.badRequest('Email required');
*/
badRequest(message?: string): AppError;
/**
* Creates a 401 Unauthorized error
* @llm-rule WHEN: Authentication is required but missing or invalid
* @llm-rule AVOID: Using for permission issues - use forbidden() for access control
* @llm-rule NOTE: EXAMPLES: missing token, invalid token, expired session
* @llm-rule NOTE: PATTERN: if (!token) throw error.unauthorized('Token required');
*/
unauthorized(message?: string): AppError;
/**
* Creates a 403 Forbidden error
* @llm-rule WHEN: User is authenticated but lacks permission for the action
* @llm-rule AVOID: Using for authentication issues - use unauthorized() instead
* @llm-rule NOTE: EXAMPLES: insufficient role, blocked user, admin-only endpoint
* @llm-rule NOTE: PATTERN: if (!user.isAdmin) throw error.forbidden('Admin access required');
*/
forbidden(message?: string): AppError;
/**
* Creates a 404 Not Found error
* @llm-rule WHEN: Requested resource does not exist
* @llm-rule AVOID: Using for business logic failures - use conflict() instead
* @llm-rule NOTE: EXAMPLES: user not found, post not found, missing file
* @llm-rule NOTE: PATTERN: if (!user) throw error.notFound('User not found');
*/
notFound(message?: string): AppError;
/**
* Creates a 409 Conflict error
* @llm-rule WHEN: Business logic conflicts or resource already exists
* @llm-rule AVOID: Using for validation errors - use badRequest() for input validation
* @llm-rule NOTE: EXAMPLES: email already exists, duplicate username, state conflicts
* @llm-rule NOTE: PATTERN: if (existingUser) throw error.conflict('Email already registered');
*/
conflict(message?: string): AppError;
/**
* Creates a 500 Server Error
* @llm-rule WHEN: Internal server failures like database errors, external API failures
* @llm-rule AVOID: Using for business logic issues - use appropriate 4xx errors instead
* @llm-rule NOTE: EXAMPLES: database connection failure, external API timeout, file system errors
* @llm-rule NOTE: PATTERN: catch (dbError) { throw error.serverError('Database unavailable'); }
*/
serverError(message?: string): AppError;
/**
* Creates a custom error with any status code
* @llm-rule WHEN: Need custom HTTP status codes not covered by semantic methods
* @llm-rule AVOID: Using for standard HTTP codes - use semantic methods instead
* @llm-rule NOTE: EXAMPLES: 429 rate limit, 503 service unavailable, 418 teapot
* @llm-rule NOTE: PATTERN: error.createError(429, 'Rate limit exceeded', 'RATE_LIMIT');
*/
createError(statusCode: number, message: string, type?: string): AppError;
/**
* Creates production-ready Express error handling middleware
* @llm-rule WHEN: Setting up Express app error handling - use as last middleware
* @llm-rule AVOID: Using multiple error handlers - this should be the final middleware
* @llm-rule NOTE: MIDDLEWARE SETUP: app.use(error.handleErrors()); // Must be LAST
* @llm-rule NOTE: AUTO-FEATURES: dev vs prod responses, stack trace hiding, error logging
*/
handleErrors(options?: ErrorHandlerOptions): ExpressErrorHandler;
/**
* Wraps async route handlers to catch errors automatically
* @llm-rule WHEN: Creating async Express route handlers that might throw errors
* @llm-rule AVOID: Manual try/catch in every route - this handles it automatically
* @llm-rule NOTE: ASYNC PATTERN: app.post('/route', error.asyncRoute(async (req, res) => {...}));
* @llm-rule NOTE: ERROR FLOW: thrown errors → automatically caught → sent to handleErrors middleware
*/
asyncRoute(fn: AsyncRouteHandler): (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void;
/**
* Checks if error is a 4xx client error
* @llm-rule WHEN: Need to categorize errors for logging or metrics
* @llm-rule AVOID: Manual status code checking - this handles the logic
* @llm-rule NOTE: CLIENT ERRORS: 400-499 status codes (user's fault)
*/
isClientError(error: AppError): boolean;
/**
* Checks if error is a 5xx server error
* @llm-rule WHEN: Need to categorize errors for monitoring or alerting
* @llm-rule AVOID: Manual status code checking - this handles the logic
* @llm-rule NOTE: SERVER ERRORS: 500-599 status codes (server's fault)
*/
isServerError(error: AppError): boolean;
/**
* Gets current environment detection info
* @llm-rule WHEN: Need to check current environment configuration
* @llm-rule AVOID: Direct process.env access - this provides parsed config
*/
getEnvironmentInfo(): {
isDevelopment: boolean;
isProduction: boolean;
nodeEnv: string;
};
/**
* Gets current error configuration
* @llm-rule WHEN: Debugging error setup or inspecting current settings
* @llm-rule AVOID: Accessing config directly - this provides clean interface
*/
getConfig(): ErrorConfig;
}
//# sourceMappingURL=error.d.ts.map