Skip to Content
Error Handling

Error Handling

Scopra is strict by default. If policy evaluation cannot complete, PolicyPipeline.evaluate(...) rejects instead of silently allowing or denying the request.

Use typed Scopra errors to separate evaluator failures from ordinary application errors.

import { isScopraError, PolicyPipeline } from "scopra"; const pipeline = new PolicyPipeline({ evaluator, policies, }); try { const decision = await pipeline.evaluate({ content: userMessage, }); if (!decision.allowed) { return decision.violations[0]?.denial ?? "This request needs review."; } return continueWorkflow(); } catch (error) { if (isScopraError(error)) { logger.warn("Scopra check failed", { code: error.code, context: error.context, cause: error.cause, }); return "This request needs review before we can continue."; } throw error; }

Error Types

ErrorCodeWhen it happens
PolicyEvaluationErrorpolicy_evaluator_failedA custom evaluator, model adapter, or provider request fails.
PolicyEvaluationErrorpolicy_findings_invalidA model evaluator returns malformed, duplicate, unknown, or missing policy findings.
ViolationResponseErrorviolation_response_failedgenerateViolationResponse(...) cannot generate user-facing denial copy.

All Scopra errors include:

type ScopraError = { name: string; code: ScopraErrorCode; message: string; cause: unknown; context: { policyIds?: readonly string[]; phase?: string; }; publicMessage: string; };

Safe Logging

error.context is safe to log by default. It includes policy ids and the Scopra phase, but not raw evaluated content.

The original provider or evaluator failure is kept in error.cause. Treat cause as sensitive because third-party SDK errors may include request details.

Response Generation Failures

generateViolationResponse(...) runs after a policy decision has already denied a request. If response generation fails, show a generic fallback denial instead of retrying the policy check.

import { generateViolationResponse, isScopraError } from "scopra"; try { return await generateViolationResponse(model, deniedDecision); } catch (error) { if (isScopraError(error)) { logger.warn("Could not generate denial copy", { code: error.code, context: error.context, }); return deniedDecision.violations[0]?.denial ?? error.publicMessage; } throw error; }
Last updated on