# Error handling

Strapi is natively handling errors with a standard format.

There are 2 use cases for error handling:

  • As a developer querying content through the REST or GraphQL APIs, you might receive errors in response to the requests.
  • As a developer customizing the backend of your Strapi application, you could use controllers and services to throw errors.

# Receiving errors

Errors are included in the response object with the error key and include information such as the HTTP status code, the name of the error, and additional information.

# REST errors

Errors thrown by the REST API are included in the response that has the following format:

{
  "data": null,
  "error": {
    "status": "", // HTTP status
    "name": "", // Strapi error name ('ApplicationError' or 'ValidationError')
    "message": "", // A human reable error message
    "details": {
      // error info specific to the error type
    }
  }
}

# GraphQL errors

Errors thrown by the GraphQL API are included in the response that has the following format:

{ "errors": [
    {
      "message": "", // A human reable error message
      "extensions": {
        "error": {
          "name": "", // Strapi error name ('ApplicationError' or 'ValidationError'),
          "message": "", // A human reable error message (same one as above);
          "details": {}, // Error info specific to the error type
        },
        "code": "" // GraphQL error code (ex: BAD_USER_INPUT)
      }
    }
  ],
  "data": {
    "graphQLQueryName": null
  }
}

# Throwing errors

The recommended way to throw errors when developing any custom logic with Strapi is to have the controller respond with the correct status and body.

This can be done by calling an error function on the context (i.e. ctx). Available error functions are listed in the http-errors documentation (opens new window) but their name should be camel-cased to be used by Strapi (e.g. badRequest).

Error functions accept 2 parameters that correspond to the error.message and error.details attributes received by a developer querying the API:

  • the first parameter of the function is the error message
  • and the second one is the object that will be set as details in the response received

// path: ./src/api/[api-name]/controllers/my-controller.js

module.exports = {
  renameDog: async (ctx, next) => {
    const newName = ctx.request.body.name;
    if (!newName) {
      return ctx.badRequest('name is missing', { foo: 'bar' })
    }
    ctx.body = strapi.service('api::dog.dog').rename(newName);
  }
}

✏️ NOTE

Services don't have access to the controller's ctx object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of calling the proper error function.