Alokai
GuidesError Handling

Validation Errors

This section covers how to handle validation errors in middleware, including automatic normalization of schema validation libraries like zod, valibot, and arktype.


Overview

ValidationError is a specialized error class for validation failures. It supports:

  • Standard Schema validation libraries (zod, valibot, arktype, etc.)
  • Structured issues with field paths and error messages
  • Automatic normalization of uncaught schema validation errors

Standard Schema is a universal interface implemented by 20+ validation libraries. When you use schema.parse() and it throws, the middleware automatically normalizes it to a ValidationError with HTTP 422 status.


Automatic Normalization

The default error handler automatically converts Standard Schema validation errors (like ZodError) to ValidationError with:

  • HTTP 422 Unprocessable Entity status code
  • Structured issues in data.issues array
  • Original error preserved in cause for debugging

How it works

When a schema validation error escapes your middleware endpoint:

// This ZodError will be automatically normalized
export const createUser = async (context, args) => {
  const schema = z.object({
    email: z.email(),
    age: z.number().min(18),
  });

  // If validation fails, ZodError is thrown
  const validated = schema.parse(args);

  // ... rest of your logic
};

The frontend receives a properly formatted response:

{
  "name": "ValidationError",
  "message": "Validation failed",
  "data": {
    "issues": [
      {
        "message": "Invalid email",
        "path": ["email"],
        "code": "invalid_string"
      },
      {
        "message": "Number must be greater than or equal to 18",
        "path": ["age"],
        "code": "too_small",
        "minimum": 18
      }
    ]
  }
}

No try/catch needed for basic validation. Just use schema.parse() and let the middleware handle the error automatically.


Type Guards

ValidationError provides static methods for type checking:

isValidationError()

Check if an error is a ValidationError (works across module boundaries):

import { ValidationError } from '@alokai/connect/middleware';

try {
  await someOperation();
} catch (error) {
  if (ValidationError.isValidationError(error)) {
    console.log('Validation issues:', error.issues);
  }
}

isStandardSchemaError()

Check if an error follows the Standard Schema format (has issues array):

import { ValidationError } from '@alokai/connect/middleware';

if (ValidationError.isStandardSchemaError(error)) {
  // It's a zod, valibot, arktype, or similar error
  const normalized = ValidationError.fromStandardSchemaError(error);
}

Supported Libraries

Any library implementing the Standard Schema specification works automatically, including zod, valibot, arktype, and 20+ others.

See the Standard Schema documentation for the complete list of supported libraries.


Best Practices

Use a validation library

Always use a proper validation library like zod, valibot, or arktype instead of manual validation:

import { z } from 'zod';

// GOOD: Use a schema validation library
const userSchema = z.object({
  email: z.email(),
  username: z.string().min(3),
  age: z.number().min(18),
});

const validated = userSchema.parse(args);

Let errors propagate

Don't wrap schema.parse() in try/catch unless you need custom handling. The middleware normalizes errors automatically:

// GOOD: Simple and clean - errors auto-normalize to 422
export const createUser = async (context, args) => {
  const validated = userSchema.parse(args);
  // ... rest of your logic
};

Use safeParse for custom error logging

// GOOD: When you need to log before the error propagates
const result = schema.safeParse(args);

if (!result.success) {
  context.logger.warn('Validation failed', {
    issues: result.error.issues,
    input: args,
  });
  throw result.error; // Let middleware normalize it
}

return processData(result.data);

On this page