Primate LogoPrimate

Errors and issue paths

Failed parsing throws ParseError:

import ParseError from "pema/ParseError";

try {
  p({ email: p.string.email() }).parse({ email: "invalid" });
} catch (error) {
  if (ParseError.is(error)) {
    console.log(error.issues);
  }
}

Use ParseError.is() rather than relying on instanceof across package or runtime boundaries.

Issues

Each entry in error.issues contains:

interface ParseIssue {
  type: IssueType;
  input: unknown;
  message: string;
  path: JSONPointer;
}

Parse issue types include invalid_type, invalid_format, too_small, too_large, out_of_range, not_in_set, duplicate and unknown_property. network_error is part of the public issue vocabulary but is not produced by schema parsing.

error.message formats the first issue. Read issues when an application needs all structured details.

JSON Pointer paths

Paths use RFC 6901 JSON Pointer syntax. Object properties append their name and array members append their numeric index:

/profile/email
/items/2/quantity

Property names escape ~ as ~0 and / as ~1. A root-value issue has the empty path "".

JSON responses

ParseError.toJSON() returns a single issue payload for root errors:

{
  "type": "invalid_type",
  "message": "expected string, got `42` (number)",
  "messages": ["expected string, got `42` (number)"]
}

Issues with paths become a path-keyed object. Multiple issues at one path share one entry and append to messages:

{
  "/email": {
    "type": "invalid_format",
    "message": "Expected an email address",
    "messages": ["Expected an email address"]
  }
}

The public Issue and JSONPayload types describe these structures. Primate automatically turns uncaught request-schema errors into 400 Bad Request; see Input validation.

Custom messages

String validators accept a message string or message option. Primitive schemas also support check(predicate, message):

const Code = p.string.regex(/^[A-Z]+$/, "Use uppercase letters");
const Even = p.u32.check(value => value % 2 === 0, "Expected an even value");

Application field errors

Use p.error(field, message) when validation depends on application state:

if (await emailExists(email)) {
  throw p.error("email", "This email is already registered");
}

It creates an invalid_format issue at /email. Primate frontend form helpers map JSON Pointer paths to their corresponding fields; nested paths are described in Forms.

Previous
Composition
Next
Stores