Error Handling Mechanism in OmniRoute: A Security-First Approach
OmniRoute implements a centralized error handling mechanism through utilities in open-sse/utils/error.ts that automatically sanitizes error messages and constructs OpenAI-compatible JSON responses, preventing any exposure of stack traces or sensitive internal details.
OmniRoute follows a strict, layered error-handling strategy designed to prevent information leakage while maintaining consistent API responses. The error handling mechanism in OmniRoute centers on two core utilities—buildErrorBody and sanitizeErrorMessage—which enforce uniform error schemas across API routes, MCP tools, and internal services according to the diegosouzapw/OmniRoute source code.
Core Error Utilities
The foundation of OmniRoute's error handling mechanism lives in open-sse/utils/error.ts, which exports functions that guarantee no raw stack traces or secret values ever leak to clients.
buildErrorBody(status, message, upstreamDetails?)
This utility constructs JSON error payloads that conform to the OpenAI-style schema of { error: { message, type?, code? } }. It automatically runs messages through sanitizeErrorMessage and removes unsafe fields (such as stack) from any upstreamDetails object provided. When an upstream provider returns an error, buildErrorBody can embed a sanitized subset in upstream_details without exposing the provider's raw stack trace.
sanitizeErrorMessage(err)
This function strips filesystem paths, stack traces, and any other potentially sensitive information from an Error object before it is logged or returned. By applying this sanitization layer first, OmniRoute ensures that logs and client responses contain only safe, non-revealing strings.
Implementation Across the Codebase
All request entry points import buildErrorBody and wrap caught exceptions with it, creating a uniform response format enforced throughout the repository.
API Routes
Every route in src/app/api/v1/** imports buildErrorBody. For example, src/app/api/v1/relay/chat/completions/route.ts implements try…catch blocks that end with new Response(JSON.stringify(buildErrorBody(...))), ensuring consistent error formatting at the edge.
MCP Server Tools
Each MCP tool validates errors through buildErrorBody. The test suite in tests/unit/plugins-route-error-sanitization.test.ts verifies that all tools adhere to this pattern, preventing regression in error sanitization coverage.
Internal Services and Logging
Core usage commands in src/lib/usage/internalUsageCommand.ts and quota-enforcement modules also call buildErrorBody to maintain consistency across background jobs. Before anything is logged, sanitizeErrorMessage is applied so that logs contain only safe strings, as implemented in src/lib/api/serverErrorMessage.ts.
Key Design Principles
OmniRoute's error handling mechanism follows four strict design rules:
- Uniform JSON shape: All error responses follow the same schema, making client-side error handling predictable across all endpoints.
- Sanitization first: Because
buildErrorBodyinternally usessanitizeErrorMessage, developers only need to remember to callbuildErrorBodyto ensure safety. - Upstream error embedding: The mechanism safely handles downstream provider failures by embedding sanitized upstream details without exposing internal error contexts.
- Hard Rule #12 enforcement: The repository contains a large test matrix asserting that every route and tool imports and uses
buildErrorBody. This rule is enforced by the CI lint checknpm run check:fabricated-docs.
Implementation Examples
The following pattern demonstrates how protected routes validate API keys while automatically sanitizing errors:
// Example: a protected route that validates an API key
import { buildErrorBody } from "@omniroute/open-sse/utils/error";
export async function GET(req: Request) {
try {
const apiKey = req.headers.get("x-api-key");
if (!apiKey) throw new Error("Missing API key");
// … normal processing …
} catch (err) {
// All errors automatically become safe JSON bodies
return new Response(JSON.stringify(buildErrorBody(401, err)), {
status: 401,
headers: { "Content-Type": "application/json" },
});
}
}
When handling downstream provider failures, the mechanism preserves safe error details:
// Example: handling a downstream provider failure
import { buildErrorBody } from "@omniroute/open-sse/utils/error";
async function callProvider() {
try {
const resp = await fetch(providerUrl);
if (!resp.ok) {
const upstream = await resp.json();
throw new Error(upstream.error?.message ?? "Provider error");
}
return await resp.json();
} catch (e) {
// Preserve a safe copy of the upstream error details
return buildErrorBody(502, "Provider returned an error", {
upstream_details: { message: e.message },
});
}
}
Summary
- OmniRoute's error handling mechanism relies on centralized utilities in
open-sse/utils/error.tsto prevent data leakage. - The
buildErrorBodyfunction generates OpenAI-compatible error schemas while automatically sanitizing messages. sanitizeErrorMessageremoves filesystem paths and stack traces before logging or responding.- Hard Rule #12 enforces these patterns through automated testing in
tests/unit/plugins-route-error-sanitization.test.ts. - All API routes, MCP tools, and internal services consistently implement this mechanism to ensure security.
Frequently Asked Questions
How does OmniRoute prevent stack traces from leaking to clients?
OmniRoute uses the sanitizeErrorMessage function in open-sse/utils/error.ts to strip filesystem paths and stack traces from error objects before they reach the response layer. This sanitization happens automatically within buildErrorBody, ensuring developers cannot accidentally expose internal implementation details.
What is Hard Rule #12 in OmniRoute's error handling?
Hard Rule #12 is a repository-wide enforcement requirement that mandates every route and tool must import and use buildErrorBody for error responses. The CI pipeline runs npm run check:fabricated-docs to verify compliance, and the test suite in tests/unit/plugins-route-error-sanitization.test.ts validates that all entry points follow this pattern.
How are upstream provider errors handled in OmniRoute?
When an upstream provider returns an error, OmniRoute's buildErrorBody function accepts an optional upstreamDetails parameter. This allows the system to embed a sanitized subset of the upstream error (typically just the message) into the response without exposing raw stack traces or provider-specific implementation details that might contain sensitive information.
Which file contains the main error sanitization logic?
The primary error sanitization logic resides in open-sse/utils/error.ts, which exports both buildErrorBody and sanitizeErrorMessage. Additionally, src/lib/api/serverErrorMessage.ts provides helper functions for converting upstream errors into sanitized bodies, ensuring consistent application of the sanitization rules across internal services.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →