Skip to main content

错误处理

¥Error handling

Strapi 本身就以标准格式处理错误。

¥Strapi is natively handling errors with a standard format.

错误处理有 2 个用例:

¥There are 2 use cases for error handling:

  • 作为通过 RESTGraphQL API 查询内容的开发者,你可能会 接收错误 来响应请求。

    ¥As a developer querying content through the REST or GraphQL APIs, you might receive errors in response to the requests.

  • 作为自定义 Strapi 应用后端的开发者,你可以使用 抛出错误 的控制器和服务。

    ¥As a developer customizing the backend of your Strapi application, you could use controllers and services to throw errors.

接收错误

¥Receiving errors

错误包含在带有 error 键的响应对象中,并包含 HTTP 状态代码、错误名称和其他信息等信息。

¥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 错误

¥REST errors

REST API 引发的错误包含在具有以下格式的 response 中:

¥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 readable error message
"details": {
// error info specific to the error type
}
}
}

GraphQL 错误

¥GraphQL errors

GraphQL API 抛出的错误包含在具有以下格式的响应中:

¥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

控制器和中间件

¥Controllers and middlewares

使用 Strapi 开发任何自定义逻辑时抛出错误的推荐方法是让 controller中间件 以正确的状态和正文进行响应。

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

这可以通过在上下文(即 ctx)上调用错误函数来完成。http 错误文档 中列出了可用的错误函数,但它们的名称应采用小驼峰式,以便 Strapi 使用(例如 badRequest)。

¥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 but their name should be lower camel-cased to be used by Strapi (e.g. badRequest).

错误函数接受 2 个参数,对应于开发者查询 API 的 error.messageerror.details 属性 received

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

  • 该函数的第一个参数是错误 message

    ¥the first parameter of the function is the error message

  • 第二个是将在收到的响应中设置为 details 的对象

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

// path: ./src/api/[api-name]/middlewares/my-middleware.js

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

服务和模型生命周期

¥Services and models lifecycles

一旦你在比控制器或中间件更深的层上工作,就会有专用的错误类可用于引发错误。这些类是 节点 Error 的扩展,专门针对某些用例。

¥Once you are working at a deeper layer than the controllers or middlewares there are dedicated error classes that can be used to throw errors. These classes are extensions of Node Error class and are specifically targeted for certain use-cases.

这些错误类是通过 @strapi/utils 包导入的,并且可以从多个不同的层调用。以下示例使用服务层,但错误类不仅限于服务和模型生命周期。在模型生命周期层中抛出错误时,建议使用 ApplicationError 类,以便在管理面板中显示正确的错误消息。

¥These error classes are imported through the @strapi/utils package and can be called from several different layers. The following examples use the service layer but error classes are not just limited to services and model lifecycles. When throwing errors in the model lifecycle layer, it's recommended to use the ApplicationError class so that proper error messages are shown in the admin panel.

注意

有关 Strapi 提供的错误类别的更多信息,请参阅 默认错误类别 部分。

¥See the default error classes section for more information on the error classes provided by Strapi.

Example: Throwing an error in a service

此示例显示封装 核心服务 并对 create 方法进行自定义验证:

¥This example shows wrapping a core service and doing a custom validation on the create method:

path: ./src/api/restaurant/services/restaurant.js

const { errors } = require('@strapi/utils');
const { ApplicationError } = errors;
const { createCoreService } = require('@strapi/strapi').factories;

module.exports = createCoreService('api::restaurant.restaurant', ({ strapi }) => ({
async create(params) {
let okay = false;

// Throwing an error will prevent the restaurant from being created
if (!okay) {
throw new ApplicationError('Something went wrong', { foo: 'bar' });
}

const result = await super.create(params);

return result;
}
});
Example: Throwing an error in a model lifecycle

此示例展示了构建 自定义模型生命周期 并能够抛出错误以停止请求并向管理面板返回正确的错误消息。一般来说,你应该只在 beforeX 生命周期中抛出错误,而不是 afterX 生命周期中。

¥This example shows building a custom model lifecycle and being able to throw an error that stops the request and will return proper error messages to the admin panel. Generally you should only throw an error in beforeX lifecycles, not afterX lifecycles.

path: ./src/api/[api-name]/content-types/[api-name]/lifecycles.js

const { errors } = require('@strapi/utils');
const { ApplicationError } = errors;

module.exports = {
beforeCreate(event) {
let okay = false;

// Throwing an error will prevent the entity from being created
if (!okay) {
throw new ApplicationError('Something went wrong', { foo: 'bar' });
}
},
};

政策

¥Policies

政策 是一种特殊类型的中间件,在控制器之前执行。它们用于检查用户是否被允许执行该操作。如果不允许用户执行该操作并且使用了 return false,则将引发一般错误。作为替代方案,你可以使用来自 Strapi ForbiddenError 类、ApplicationError 类(请参阅 默认错误类别 的两个类)以及最后的 节点 Error 的嵌套类扩展来抛出自定义错误消息。

¥Policies are a special type of middleware that are executed before a controller. They are used to check if the user is allowed to perform the action or not. If the user is not allowed to perform the action and a return false is used then a generic error will be thrown. As an alternative, you can throw a custom error message using a nested class extensions from the Strapi ForbiddenError class, ApplicationError class (see Default error classes for both classes), and finally the Node Error class.

PolicyError 类可从 @strapi/utils 包中获取,并接受 2 个参数:

¥The PolicyError class is available from @strapi/utils package and accepts 2 parameters:

  • 该函数的第一个参数是错误 message

    ¥the first parameter of the function is the error message

  • (可选)第二个参数是将在收到的响应中设置为 details 的对象;最佳实践是使用引发错误的策略名称设置 policy 键。

    ¥(optional) the second parameter is the object that will be set as details in the response received; a best practice is to set a policy key with the name of the policy that threw the error.

Example: Throwing a PolicyError in a custom policy

此示例显示构建一个 定制政策,该 定制政策 将抛出自定义错误消息并停止请求。

¥This example shows building a custom policy that will throw a custom error message and stop the request.

path: ./src/api/[api-name]/policies/my-policy.js

const { errors } = require('@strapi/utils');
const { PolicyError } = errors;

module.exports = (policyContext, config, { strapi }) => {
let isAllowed = false;

if (isAllowed) {
return true;
} else {
throw new PolicyError('You are not allowed to perform this action', {
policy: 'my-policy',
myCustomKey: 'myCustomValue',
});
}
}

默认错误类别

¥Default error classes

默认错误类可从 @strapi/utils 包中获取,并且可以在代码中导入和使用。任何默认错误类都可以扩展以创建自定义错误类。然后可以在代码中使用自定义错误类来引发错误。

¥The default error classes are available from the @strapi/utils package and can be imported and used in your code. Any of the default error classes can be extended to create a custom error class. The custom error class can then be used in your code to throw errors.

ApplicationError 类是应用错误的通用错误类,通常建议作为默认错误类。此类专门设计用于抛出管理面板可以读取并向用户显示的正确错误消息。它接受以下参数:

¥The ApplicationError class is a generic error class for application errors and is generally recommended as the default error class. This class is specifically designed to throw proper error messages that the admin panel can read and show to the user. It accepts the following parameters:

范围类型描述默认
messagestring错误信息An application error occured
detailsobject定义附加细节的对象{}
throw new ApplicationError('Something went wrong', { foo: 'bar' });