Skip to main content
Version: Next

Errors and Validation Results

This page contains information about how you can determine if a request has been valid. It also documents all possible validation error types.

validationResult()

validationResult(req: Request): Result<ValidationError>

Extracts the validation results from a request, wraps them in a Result object, and returns it.

const { query, validationResult } = require('express-validator');

app.post('/hello', query('person').notEmpty(), (req, res) => {
const result = validationResult(req);
// Use `result` to figure out if the request is valid or not
});

withDefaults()

validationResult.withDefaults<T>(options: { formatter?: ErrorFormatter<T> }): ResultFactory<T>

Creates a new validationResult()-like function that uses the provided options as the defaults in the returned Result object.

For example, it's possible to set the default error formatter of a result like this:

const { query, validationResult } = require('express-validator');
const myValidationResult = validationResult.withDefaults({
formatter: error => error.msg,
});

app.post('/hello', query('person').notEmpty(), (req, res) => {
const errors = myValidationResult(req).array();
// => ['Invalid value']
});

ResultFactory<T>

Result<T>

The result object is a wrapper around the validation state of a request. It provides a couple of methods that you can use to determine if the request is valid or not.

info

The type parameter T refers to the type that errors as returned by methods such as .array() and .mapped() will have.

Its default is ValidationError, which can be changed by using .formatWith().

.isEmpty()

isEmpty(): boolean

Returns whether the request contains validation errors, and therefore whether it's valid or not.

.formatWith()

formatWith<T>(formatter: ErrorFormatter<T>): Result<T>

Rewraps the validation state in a new Result object that uses formatter as its error formatter.

💭 Why does this method return a new Result?

If you've read through other pages of this documentation, you might be asking yourself why can't .formatWith() mutate itself, like validation chains do?

The reason for this is simple: TypeScript.
It's not possible to change the generic type of an existing object. If some code references the result as Result<{ error: string }>, but after formatWith it's now actually Result<{ message: string }>, some code consuming the old Result type would not get compile-time errors about the type mismatch.

const { query, validationResult } = require('express-validator');

app.post('/hello', query('person').notEmpty(), (req, res) => {
const result = validationResult(req);
const errors = result.array();
// => [{ msg: 'Invalid value', ... }]

const result2 = result.formatWith(error => error.msg);
const errors2 = result2.array();
// => ['Invalid value']
});

.array()

array(options?: { onlyFirstError?: boolean }): T[]

Returns a list of all errors from all validated fields.

const result = validationResult(req).array();
// => [{ msg: 'Invalid value', path: 'field1' }, { msg: 'Invalid value', path: 'field1' }]

When options.onlyFirstError is set to true, then only the first error of each field is returned:

const result = validationResult(req).array({ onlyFirstError: true });
// => [{ msg: 'Invalid value', path: 'field1' }]

.mapped()

mapped(): Record<string, T>

Returns an object from field path to error. If a field has multiple errors, only the first one is returned.

const result = validationResult(req).mapped();
// => { field1: { msg: 'Invalid value', ... }, field2: { msg: 'Invalid value', ... } }

.throw()

throw(): void

If the result object has errors, then this method throws an error decorated with the same methods as the Result type.
This is useful if you wish to forward the errors to the error handler middleware of your express.js application, for example.

If the result object has no errors, then this method does nothing.

app.post('/hello', query('person').notEmpty(), (req, res) => {
try {
validationResult(req).throw();
res.send(`Hello, ${req.query.person}!`);
} catch (e) {
res.status(400).send({ errors: e.mapped() });
}
});

Error types

Different APIs in express-validator cause different types of validation errors. All of them are documented here:

FieldValidationError

type FieldValidationError = {
type: 'field';
location: Location;
path: string;
value: any;
msg: any;
};

Represents an error caused when validating a single field, simple as that.

AlternativeValidationError

type AlternativeValidationError = {
type: 'alternative';
msg: any;
nestedErrors: FieldValidationError[];
};

Represents an error caused when all alternatives (e.g. in oneOf()) were invalid. nestedErrors contains a flat list of the individual field errors.

GroupedAlternativeValidationError

type AlternativeValidationError = {
type: 'alternative_grouped';
msg: any;
nestedErrors: FieldValidationError[][];
};

Represents an error caused when all alternatives (e.g. in oneOf()) were invalid. nestedErrors contains the list of the individual field errors, grouped by the alternative.

UnknownFieldValidationError

type UnknownFieldsError = {
type: 'unknown_fields';
msg: any;
fields: { path: string; location: Location; value: any }[];
};

Represents an error caused when one or more fields are unknown; that is, they didn't have a validation chain when checkExact() kicked off. fields contains the list of all unknown fields' paths, locations and values.

ValidationError

Any of the validation errors. It's possible to determine what the error actually is by looking at its type property:

switch (error.type) {
case 'field':
// `error` is a `FieldValidationError`
console.log(error.path, error.location, error.value);
break;

case 'alternative':
// `error` is an `AlternativeValidationError`
console.log(error.nestedErrors);
break;

case 'alternative_grouped':
// `error` is a `GroupedAlternativeValidationError`
error.nestedErrors.forEach((nestedErrors, i) => {
console.log(`Errors from chain ${i}:`);
console.log(nestedErrors);
});
break;

case 'unknown_fields':
// `error` is an `UnknownFieldsError`
console.log(error.fields);
break;

default:
// Error is not any of the known types! Do something else.
throw new Error(`Unknown error type ${error.type}`);
}
info

If you're using TypeScript, this technique is known as discriminated unions.

ErrorFormatter<T>

type ErrorFormatter<T> = (error: ValidationError) => T;

A function used to format errors returned by methods such as Result#mapped() and Result#array(). It takes the unformatted error and must return a new value.