different-ai/openwork · info

${error} (sanitized request error)

Error message

${error} (sanitized request error)

What it means

createTelemetryErrorSanitizerMiddleware is a Hono middleware that wraps the downstream handler. After next() it rewrites any error set on the context, and any thrown exception, through sanitizeRequestError so that upstream request errors reaching telemetry/clients never leak internal details (URLs, headers, stack internals). It throws the sanitized error so outer handlers still see an Error.

Source

Thrown at ee/apps/den-api/src/observability/hono.ts:96

  if (error instanceof HTTPException) {
    return new HTTPException(error.status, {
      message: sanitizeText(error.message),
      res: error.res,
    })
  }

  return sanitizeExceptionForTelemetry(error)
}

export function createTelemetryErrorSanitizerMiddleware(): MiddlewareHandler {
  return async (c, next) => {
    try {
      await next()
      if (c.error) {
        c.error = sanitizeRequestError(c.error)
      }
    } catch (error) {
      throw sanitizeRequestError(error)
    }
  }
}

type ErrorResponseFactory<E extends Env> = (error: Error, c: Context<E>, requestId: string) => Response | undefined | Promise<Response | undefined>

export function registerAppErrorHandler<E extends Env>(app: Hono<E>, responseForError?: ErrorResponseFactory<E>) {
  const logger = appLogger.child({ component: "http" })

  app.onError(async (error, c) => {
    const safeError = sanitizeRequestError(error)
    const status = statusFromError(safeError)
    const requestId = c.get("requestId")
    const fields = {
      request_id: typeof requestId === "string" ? requestId : undefined,
      http_method: c.req.method,
      http_route: normalizedHonoRoute(c),
      http_status_code: status,

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Fix the root cause of the original downstream error — the sanitized error intentionally hides detail, so check server logs/telemetry for the pre-sanitization error.
  2. If the message looks wrong, verify the thrown value is an Error instance (not a string/object) so sanitization preserves its message.
  3. Ensure this middleware is only applied to request-facing routes, not internal ones where full detail is needed.
  4. If you need the raw error for debugging, log it before sanitization inside the handler.

Example fix

// before
throw "upstream fetch failed for https://internal.host/key"
// after
throw new Error("upstream fetch failed")
Defensive patterns

Strategy: try-catch

Validate before calling

if (!(value instanceof Error)) value = new Error(String(value))

Type guard

function isError(e: unknown): e is Error { return e instanceof Error }

Try / catch

try { await callApi() } catch (e) { logger.error('pre-sanitization', e); /* response is sanitized by middleware */ }

Prevention

When it happens

Trigger: Any downstream route handler throws an exception, or sets c.error, while this middleware is registered; the middleware intercepts it and re-throws the sanitized version (message becomes `${error} (sanitized request error)` for unknown shapes).

Common situations: A fetch to an upstream provider fails with a verbose Axios/fetch error; a DB error contains connection strings; an unexpected non-Error value is thrown and gets stringified with the suffix.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/1c0f0a324ca34261. Report an issue: GitHub.