Package Exports
- @ticatec/node-exception
- @ticatec/node-exception/lib/ErrorResponse
- @ticatec/node-exception/lib/HttpError
- @ticatec/node-exception/lib/utils
- @ticatec/node-exception/package.json
Readme
@ticatec/node-exception
δΈζ | English
A comprehensive, production-ready error handling library for Node.js Express applications. This library provides standardized error types, centralized error handling middleware, and consistent response formats with flexible content negotiation support.
π Features
- π― Standardized Error Types: Eight predefined error classes covering common HTTP scenarios
- π§ Express Middleware: Drop-in error handling middleware with zero configuration
- π Consistent Response Format: Uniform error responses with comprehensive request context
- π¨ Content Negotiation: Automatic response formatting (JSON, HTML, plain text)
- π Development Support: Stack trace inclusion in development environments
- π TypeScript First: Full TypeScript support with complete type definitions
- π Logging Integration: Built-in log4js integration for comprehensive error tracking
- π IP Detection: Automatic client and server IP address detection
- β‘ Zero Dependencies: Minimal runtime footprint with only essential dependencies
π¦ Installation
npm install @ticatec/node-exception
Peer Dependencies
npm install log4js
π§ Quick Start
import express from 'express';
import { handleError, AppError, UnauthenticatedError } from '@ticatec/node-exception';
const app = express();
// Your API routes
app.get('/api/protected', (req, res, next) => {
try {
if (!req.headers.authorization) {
throw new UnauthenticatedError();
}
res.json({ message: 'Success!' });
} catch (error) {
next(error);
}
});
// Error handling middleware (must be the last middleware)
app.use((err, req, res, next) => {
handleError(err, req, res);
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
π Error Types & Usage
π AppError
Generic application error with custom error codes for business logic errors.
// Database errors
throw new AppError(1001, "Database connection failed");
// Business logic errors
throw new AppError(2001, "Insufficient account balance");
// Validation errors
throw new AppError(3001, "User email already exists");
π« UnauthenticatedError
For authentication failures (HTTP 401).
// Missing authentication
if (!req.headers.authorization) {
throw new UnauthenticatedError();
}
// Invalid token
if (!isValidToken(token)) {
throw new UnauthenticatedError();
}
π InsufficientPermissionError
For authorization failures (HTTP 403).
// Role-based access control
if (!user.hasRole('admin')) {
throw new InsufficientPermissionError();
}
// Resource ownership
if (resource.ownerId !== user.id) {
throw new InsufficientPermissionError();
}
β IllegalParameterError
For input validation failures (HTTP 400).
// Email validation
if (!isValidEmail(email)) {
throw new IllegalParameterError("Invalid email format");
}
// Required field validation
if (!userId) {
throw new IllegalParameterError("User ID is required");
}
// Range validation
if (age < 0 || age > 150) {
throw new IllegalParameterError("Age must be between 0 and 150");
}
π ActionNotFoundError
For non-existent routes or resources (HTTP 404).
// Route not found
if (!routeExists(req.path)) {
throw new ActionNotFoundError();
}
// Resource not found
if (!user) {
throw new ActionNotFoundError();
}
β±οΈ TimeoutError
For request timeouts (HTTP 408).
// Database query timeout
if (Date.now() - startTime > TIMEOUT_LIMIT) {
throw new TimeoutError();
}
// API request timeout
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new TimeoutError()), 5000);
});
π ProxyError
For proxy server issues (HTTP 502).
// Proxy server failure
if (!proxyResponse.ok) {
throw new ProxyError();
}
// Gateway error
if (!upstreamServer.isHealthy()) {
throw new ProxyError();
}
π« ServiceUnavailableError
For service unavailability (HTTP 503).
// Service maintenance
if (isMaintenanceMode()) {
throw new ServiceUnavailableError();
}
// Server overload
if (activeConnections > maxConnections) {
throw new ServiceUnavailableError();
}
π¨ Response Format & Content Negotiation
The library automatically handles content negotiation based on the Accept
header:
JSON Response (Default)
{
"code": -1,
"client": "192.168.1.50",
"path": "/api/users",
"method": "GET",
"timestamp": 1699123456789,
"message": "Unauthenticated user is accessing the system.",
"stack": "Error: ... (development only)"
}
HTML Response
When Accept: text/html
is requested:
<h1>Error</h1>
<p><strong>Code:</strong> -1</p>
<p><strong>Message:</strong> Unauthenticated user is accessing the system.</p>
<p><strong>Path:</strong> /api/users</p>
<p><strong>Method:</strong> GET</p>
<p><strong>Timestamp:</strong> 1699123456789</p>
Plain Text Response
When Accept: text/plain
is requested:
Error Code: -1
Message: Unauthenticated user is accessing the system.
Path: /api/users
Method: GET
Timestamp: 1699123456789
π Response Fields
Field | Type | Description |
---|---|---|
code |
number | Application-specific error code (-1 for generic errors) |
client |
string | Client IP address |
path |
string | Full request path (baseUrl + path) |
method |
string | HTTP method (GET, POST, PUT, DELETE, etc.) |
timestamp |
number | Unix timestamp in milliseconds |
message |
string | null | Human-readable error message |
stack |
string | Stack trace (development environments only) |
π Development vs Production
Stack traces are automatically included in development environments:
// Enable development mode by setting request header
fetch('/api/users', {
headers: {
'env': 'development' // or 'dev'
}
});
π¦ HTTP Status Code Mapping
Error Type | HTTP Status | Use Case |
---|---|---|
UnauthenticatedError |
401 Unauthorized | Missing or invalid authentication |
InsufficientPermissionError |
403 Forbidden | Insufficient permissions/authorization |
IllegalParameterError |
400 Bad Request | Invalid input parameters or validation |
ActionNotFoundError |
404 Not Found | Non-existent routes or resources |
TimeoutError |
408 Request Timeout | Network requests or operations timeout |
AppError |
500 Internal Server Error | Business logic or application errors |
ProxyError |
502 Bad Gateway | Proxy server or gateway issues |
ServiceUnavailableError |
503 Service Unavailable | Service maintenance or overload |
Other errors | 500 Internal Server Error | Unexpected system errors |
π‘ Advanced Usage
Custom HTTP Container
Create custom HTTP adapters for different frameworks:
import { setHttpContainer, HttpContainer } from '@ticatec/node-exception';
class CustomContainer implements HttpContainer {
getRemoteIp(req) {
return req.connection.remoteAddress;
}
getPath(req) {
return req.originalUrl;
}
sendError(req, res, statusCode, data) {
res.status(statusCode).json(data);
}
}
setHttpContainer(new CustomContainer());
Error Code Conventions
Organize your error codes systematically:
// Authentication errors: 1000-1999
const AUTH_ERRORS = {
INVALID_TOKEN: 1001,
EXPIRED_TOKEN: 1002,
MISSING_TOKEN: 1003
};
// Validation errors: 2000-2999
const VALIDATION_ERRORS = {
INVALID_EMAIL: 2001,
WEAK_PASSWORD: 2002,
REQUIRED_FIELD: 2003
};
// Business logic errors: 3000-3999
const BUSINESS_ERRORS = {
INSUFFICIENT_BALANCE: 3001,
DUPLICATE_EMAIL: 3002,
LIMIT_EXCEEDED: 3003
};
throw new AppError(AUTH_ERRORS.INVALID_TOKEN, "Authentication token is invalid");
π§ TypeScript Integration
Full TypeScript support with comprehensive type definitions:
import {
AppError,
UnauthenticatedError,
InsufficientPermissionError,
IllegalParameterError,
ActionNotFoundError,
handleError
} from '@ticatec/node-exception';
import { Request, Response, NextFunction } from 'express';
// Type-safe error middleware
const errorHandler = (
err: AppError | Error,
req: Request,
res: Response,
next: NextFunction
): void => {
handleError(err, req, res);
};
// Custom error with proper typing
class CustomValidationError extends IllegalParameterError {
constructor(field: string, value: any) {
super(`Invalid ${field}: ${value}`);
}
}
ποΈ Architecture
The library uses a modular architecture with clear separation of concerns:
- Error Classes (
Errors.ts
): Standardized error types with global registration - Error Handler (
handleError.ts
): Central error processing and response logic - HTTP Container (
HttpContainer.ts
): Framework-agnostic HTTP abstraction - Response Types (
ErrorResponse.ts
): Standardized response structure - Utilities (
utils.ts
): Response formatting helpers
π Requirements
- Node.js: β₯14.0.0
- npm: β₯6.0.0
- log4js: ^6.7.0 (peer dependency)
π€ Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Development Setup
git clone https://github.com/ticatec/node-exception.git
cd node-exception
npm install
npm run dev # Start development mode
npm run build # Build the library
npm run typecheck # Type checking
π License
MIT Β© Henry Feng
π Links
- GitHub Repository: https://github.com/ticatec/node-exception
- npm Package: https://www.npmjs.com/package/@ticatec/node-exception
- Issues: https://github.com/ticatec/node-exception/issues
- Documentation: https://docs.ticatec.com/node-exception