Asynchronous HTTP microservices framework with built-in body parsing and error handling
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
HTTP error creation and handling system with status codes and structured error responses for microservices.
Custom error class that extends the standard Error with HTTP-specific properties for status codes and error chaining.
/**
* HTTP-specific error class with status code support
*/
class HttpError extends Error {
constructor(message: string);
/** HTTP status code to send with error response */
statusCode?: number;
/** Reference to original error if this error wraps another */
originalError?: Error;
}Usage Examples:
import { HttpError } from "micro";
// Create basic HTTP error
const error = new HttpError("User not found");
error.statusCode = 404;
// Create with original error reference
const dbError = new Error("Connection timeout");
const httpError = new HttpError("Database unavailable");
httpError.statusCode = 503;
httpError.originalError = dbError;
// Throw in handler
const handler = async (req, res) => {
const userId = req.url?.split("/").pop();
if (!userId) {
const error = new HttpError("User ID is required");
error.statusCode = 400;
throw error;
}
const user = await findUser(userId);
if (!user) {
const error = new HttpError("User not found");
error.statusCode = 404;
throw error;
}
return user;
};Utility function for creating HttpError instances with status codes and original error references in a single call.
/**
* Creates HttpError with status code and original error reference
* @param code - HTTP status code for the error
* @param message - Human-readable error message
* @param original - Original error that caused this HTTP error
* @returns HttpError instance with all properties set
*/
function createError(code: number, message: string, original: Error): HttpError;Usage Examples:
import { createError } from "micro";
// Basic error creation
const error = createError(400, "Invalid email format", new Error("Validation failed"));
// In request handlers
const validationHandler = async (req, res) => {
try {
const data = await json(req);
if (!data.email || !data.email.includes("@")) {
throw createError(400, "Valid email is required", new Error("Email validation failed"));
}
return { success: true };
} catch (parseError) {
if (parseError instanceof Error && parseError.message.includes("JSON")) {
throw createError(400, "Invalid JSON in request body", parseError);
}
throw parseError;
}
};
// Database operation errors
const databaseHandler = async (req, res) => {
try {
const result = await database.query("SELECT * FROM users");
return result;
} catch (dbError) {
if (dbError.code === "ECONNREFUSED") {
throw createError(503, "Service temporarily unavailable", dbError as Error);
}
if (dbError.code === "EACCES") {
throw createError(500, "Internal server error", dbError as Error);
}
throw createError(500, "Database operation failed", dbError as Error);
}
};import { createError, json } from "micro";
const validateUser = (userData: any) => {
const errors: string[] = [];
if (!userData.name || userData.name.trim().length < 2) {
errors.push("Name must be at least 2 characters");
}
if (!userData.email || !userData.email.includes("@")) {
errors.push("Valid email is required");
}
if (!userData.age || userData.age < 18) {
errors.push("Age must be 18 or older");
}
if (errors.length > 0) {
throw createError(400, `Validation failed: ${errors.join(", ")}`, new Error("Validation"));
}
};
const userHandler = async (req, res) => {
const userData = await json(req);
validateUser(userData);
// Process valid user data
return { success: true, user: userData };
};import { createError } from "micro";
const authenticateUser = (token: string) => {
if (!token) {
throw createError(401, "Authentication token required", new Error("Missing token"));
}
if (!token.startsWith("Bearer ")) {
throw createError(401, "Invalid token format", new Error("Invalid format"));
}
const jwt = token.substring(7);
try {
return verifyToken(jwt);
} catch (error) {
throw createError(401, "Invalid or expired token", error as Error);
}
};
const protectedHandler = async (req, res) => {
const token = req.headers.authorization;
const user = authenticateUser(token as string);
return { message: `Hello ${user.name}`, data: "protected content" };
};import { createError } from "micro";
const rateLimitMap = new Map<string, { count: number; resetTime: number }>();
const checkRateLimit = (clientId: string, limit: number = 100, windowMs: number = 60000) => {
const now = Date.now();
const clientData = rateLimitMap.get(clientId);
if (!clientData || now > clientData.resetTime) {
rateLimitMap.set(clientId, { count: 1, resetTime: now + windowMs });
return;
}
if (clientData.count >= limit) {
const resetIn = Math.ceil((clientData.resetTime - now) / 1000);
throw createError(
429,
`Rate limit exceeded. Try again in ${resetIn} seconds`,
new Error("Rate limit")
);
}
clientData.count++;
};
const rateLimitedHandler = async (req, res) => {
const clientIp = req.socket.remoteAddress || "unknown";
checkRateLimit(clientIp);
return { message: "Request processed successfully" };
};import { sendError, createError } from "micro";
const consistentErrorHandler = async (req, res) => {
try {
// Your application logic
throw new Error("Something went wrong");
} catch (error) {
// Convert to structured HTTP error
const httpError = createError(
500,
"Internal server error occurred",
error as Error
);
// Send structured error response
sendError(req, res, httpError);
}
};
// Custom error formatting
const customErrorHandler = async (req, res) => {
try {
// Your application logic
} catch (error) {
if (error instanceof HttpError) {
send(res, error.statusCode || 500, {
error: {
message: error.message,
code: error.statusCode,
timestamp: new Date().toISOString(),
path: req.url
}
});
} else {
send(res, 500, {
error: {
message: "Internal server error",
code: 500,
timestamp: new Date().toISOString(),
path: req.url
}
});
}
}
};