format-the-error
v1.0.1
Published
A utility library for standardizing and formatting error objects and also providing client-safe error handling.
Downloads
6
Maintainers
Readme
FormatError
A utility library for standardizing and formatting error objects in JavaScript/TypeScript applications. Provides both detailed error formatting for server-side logging and sanitized error formatting for client-side security.
Installation
npm install format-the-error
# or
yarn add format-the-errorUsage
import { getErrorMessage, toStandardError, toClientSafeError, noThrow, noThrowClientSafe, logError, getErrorDetails } from "format-the-error";
// Convert any error type to a standard format (for server-side logging)
try {
// Some code that might throw
} catch (error) {
const standardError = toStandardError(error);
console.log(standardError.message);
console.log(standardError.code); // if available
console.log(standardError.status); // if available
console.log(standardError.stack); // stack trace for debugging
console.log(standardError.originalError); // original error object
}
// Convert to client-safe error (for API responses)
try {
// Some code that might throw
} catch (error) {
const safeError = toClientSafeError(error, "Something went wrong", ["VALIDATION_ERROR"]);
res.json({ error: safeError }); // Safe to send to client
}
// Use noThrow for server-side operations (preserves all error details)
const serverResult = noThrow(() => {
return JSON.parse(jsonString); // Might throw
});
// Check if result is an error: if (isStandardizedError(serverResult)) { ... }
// Use noThrowClientSafe for client-facing operations (sanitized errors)
const clientResult = noThrowClientSafe(() => processUserInput(input), "Invalid input provided", ["VALIDATION_ERROR", "FORMAT_ERROR"]);
// Handle async operations with noThrow
const asyncServerResult = noThrow(() => fetch("/api/data"));
const asyncClientResult = noThrowClientSafe(() => fetch("/api/user"), "Request failed");
// Get a human-readable error message
const message = getErrorMessage(error);
console.log(message);
// Extract error details including stack trace
const { message, stack } = getErrorDetails(error);
// Log an error with stack trace
logError(error);API
toStandardError(error: unknown, fallbackMessage?: string): StandardizedError
Converts any error type to a standardized Error object with full details including stack traces, original error, and all properties. Ideal for server-side logging and debugging.
Returns: StandardizedError with properties:
message: string- Error messagecode?: string- Error codestatus?: number- HTTP status codestack?: string- Stack traceoriginalError?: unknown- Original error objectdata?: unknown- Additional error data
toClientSafeError(error: unknown, fallbackMessage?: string, allowedCodes?: string[]): ClientSafeError
Converts any error type to a client-safe error object that excludes sensitive information like stack traces and internal data. Perfect for API responses.
Parameters:
error- Any error valuefallbackMessage- Custom fallback message (default: "An error occurred")allowedCodes- Array of error codes safe to expose to client
Returns: ClientSafeError with properties:
message: string- Sanitized error messagecode?: string- Error code (only if in allowedCodes)status?: number- HTTP status code (sanitized for 5xx errors)
noThrow<A>(action: () => A): A | StandardizedError
Safely executes a function and returns either the result or a standardized error object. Works with both synchronous and asynchronous functions. Preserves all error details for server-side debugging.
Parameters:
action- Function to execute safely
Returns: Either the function result or a StandardizedError object
noThrowClientSafe<A>(action: () => A, fallbackMessage?: string, allowedCodes?: string[]): A | ClientSafeError
Safely executes a function and returns either the result or a client-safe error object. Works with both synchronous and asynchronous functions. Sanitizes errors for client-side security.
Parameters:
action- Function to execute safelyfallbackMessage- Custom fallback message (default: "An error occurred")allowedCodes- Array of error codes safe to expose to client
Returns: Either the function result or a ClientSafeError object
getErrorMessage(error: unknown, fallbackMessage?: string): string
Extracts a human-readable error message from different error types.
getErrorDetails(error: unknown): { message: string; stack?: string }
Extracts both the error message and stack trace if available.
logError(error: unknown, logger?: Function, prefix?: string): string
Combines error handling with logging.
isError(value: unknown): value is Error
Type guard to check if a value is an Error object.
isErrorLike(value: unknown): value is ErrorLike
Type guard for objects with a message property.
isStandardizedError(value: unknown): value is StandardizedError
Type guard to check if a value is a standardized error object.
Security Features
- Server-side: Use
toStandardError()andnoThrow()for comprehensive error logging with full details - Client-side: Use
toClientSafeError()andnoThrowClientSafe()to prevent sensitive information leakage:- Excludes stack traces
- Excludes original error objects
- Excludes internal data
- Sanitizes 5xx server errors to generic messages
- Filters error codes through whitelist
- Protects against prototype pollution
- Validates input types and lengths
Examples
Basic Error Handling with noThrow
import { noThrow, noThrowClientSafe, isStandardizedError } from "format-the-error";
// Server-side: Get full error details
const parseResult = noThrow(() => JSON.parse(userInput));
if (isStandardizedError(parseResult)) {
console.error("Parse failed:", parseResult.stack);
// Log to database/monitoring service
} else {
console.log("Parsed successfully:", parseResult);
}
// Client-side: Get sanitized errors
const clientResult = noThrowClientSafe(() => validateUserData(data), "Validation failed", ["REQUIRED_FIELD", "INVALID_FORMAT"]);
if ("message" in clientResult && typeof clientResult.message === "string") {
// It's an error - safe to send to client
return res.status(400).json({ error: clientResult });
} else {
// Success
return res.json({ data: clientResult });
}Async Operations
// Server-side async with full error details
const serverData = await noThrow(() => fetch("/internal-api").then((r) => r.json()));
// Client-side async with sanitized errors
const clientData = await noThrowClientSafe(() => fetch("/public-api").then((r) => r.json()), "Failed to load data");Mixed Error Handling Patterns
import { toStandardError, noThrow, isStandardizedError } from "format-the-error";
// Example: Fetch data with manual promise error handling, then parse with noThrow
async function fetchAndParseData(url: string) {
// Method 1: Using .catch() directly with toStandardError
const fetchDataResponse = await fetch(url).catch(toStandardError);
// Check if fetch failed
if (isStandardizedError(fetchDataResponse)) {
console.error("Fetch failed:", fetchDataResponse.message);
return fetchDataResponse; // Return the error
}
// Get response text
const fetchDataText = await fetchDataResponse.text().catch(toStandardError);
if (isStandardizedError(fetchDataText)) {
console.error("Failed to get response text:", fetchDataText.message);
return fetchDataText;
}
// Method 2: Using noThrow for JSON parsing
const parseResult = noThrow(() => JSON.parse(fetchDataText));
if (isStandardizedError(parseResult)) {
console.error("JSON parse failed:", parseResult.message);
return parseResult;
}
return parseResult; // Successfully parsed data
}
// Usage
const result = await fetchAndParseData("https://api.example.com/data");
if (isStandardizedError(result)) {
// Handle error
console.error("Operation failed:", result.message);
} else {
// Use the data
console.log("Data received:", result);
}Express.js Error Handling
import { toStandardError, toClientSafeError } from "format-the-error";
app.use((error, req, res, next) => {
// Log full error details for debugging
const fullError = toStandardError(error);
console.error("Server Error:", fullError);
// Send sanitized error to client
const clientError = toClientSafeError(error, "Something went wrong", ["VALIDATION_ERROR", "NOT_FOUND"]);
res.status(clientError.status || 500).json({ error: clientError });
});Database Error Logging
import { toStandardError } from "format-the-error";
try {
await database.query(sql);
} catch (error) {
const standardError = toStandardError(error);
await errorLogger.log({
message: standardError.message,
stack: standardError.stack,
code: standardError.code,
originalError: standardError.originalError,
timestamp: new Date(),
});
}License
MIT
