Vue Storefront is now Alokai! Learn More
Validation Errors

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);