CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-micro

Asynchronous HTTP microservices framework with built-in body parsing and error handling

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

error-management.mddocs/

Error Management

HTTP error creation and handling system with status codes and structured error responses for microservices.

Capabilities

HttpError Class

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;
};

Create Error Function

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);
  }
};

Error Handling Patterns

Validation Errors

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 };
};

Authentication Errors

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" };
};

Rate Limiting Errors

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" };
};

Error Response Format

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
        }
      });
    }
  }
};

docs

body-parsing.md

cli.md

error-management.md

index.md

response-handling.md

server.md

tile.json