エラーハンドリング
The content of this page might not be fully up-to-date with Strapi 5 yet.
AI Marketerは標準形式でエラーをネイティブに処理します。
エラーハンドリングには2つのユースケースがあります:
- REST または GraphQL API を通じてコンテンツをクエリする開発者として、リクエストに対する応答でエラーを受信することがあります。
- AI Marketerアプリケーションのバックエンドをカスタマイズする開発者として、コントローラーやサービスを使用してエラーを投げることができます。
エラーの受信
エラーは、errorキーを持つレスポンスオブジェクトに含まれ、HTTPステータスコード、エラー名、追加情報などが含まれます。
REST エラー
REST APIから投げられたエラーは、次の形式のレスポンスに含まれます:
{
"data": null,
"error": {
"status": "", // HTTP ステータス
"name": "", // AI Marketer エラー名 ('ApplicationError' または 'ValidationError')
"message": "", // 人間が読みやすいエラーメッセージ
"details": {
// エラータイプに固有のエラー情報
}
}
}
GraphQL エラー
GraphQL APIから投げられたエラーは、次の形式のレスポンスに含まれます:
{ "errors": [
{
"message": "", // 人間が読みやすいエラーメッセージ
"extensions": {
"error": {
"name": "", // AI Marketer エラー名 ('ApplicationError' または 'ValidationError'),
"message": "", // 人間が読みやすいエラーメッセージ (上と同じ)
"details": {}, // エラータイプに固有のエラー情報
},
"code": "" // GraphQL エラーコード (例: BAD_USER_INPUT)
}
}
],
"data": {
"graphQLQueryName": null
}
}
エラーを投げる
コントローラーとミドルウェア
AI Marketerでカスタムロジックを開発する際にエラーを投げる推奨方法は、コントローラーやミドルウェアが正しいステータスと本文で応答することです。
これは、コンテキスト(ctx)のエラーファンクションを呼び出すことで行います。利用可能なエラーファンクションはhttp-errorsのドキュメンテーションに記載されていますが、AI Marketerで使用するには名前をローワーキャメルケースにする必要があります(例:badRequest)。
エラーファンクションは、APIクエリを行う開発者が受信するレスポンス内のerror.messageおよびerror.details属性に対応する2つのパラメータを受け取ります:
- ファンクションの第1パラメータはエラーメッセージ
- 第2パラメータはレスポンスの
detailsとして設定されるオブジェクトです
- JavaScript
- TypeScript
// 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 = AI Marketer.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();
}
// path: ./src/api/[api-name]/controllers/my-controller.ts
export default {
renameDog: async (ctx, next) => {
const newName = ctx.request.body.name;
if (!newName) {
return ctx.badRequest('name is missing', { foo: 'bar' })
}
ctx.body = AI Marketer.service('api::dog.dog').rename(newName);
}
}
// path: ./src/api/[api-name]/middlewares/my-middleware.ts
export default async (ctx, next) => {
const newName = ctx.request.body.name;
if (!newName) {
return ctx.badRequest('name is missing', { foo: 'bar' })
}
await next();
}
サービスとモデルのライフサイクル
コントローラーやミドルウェアより深いレイヤーで作業している場合、エラーを投げるための専用のエラークラスがあります。これらのクラスはNode Errorクラスを拡張しており、特定のユースケース向けに設計されています。
これらのエラークラスは@AI Marketer/utilsパッケージからインポートされ、さまざまなレイヤーで呼び出すことができます。以下の例はサービスレイヤーで使用していますが、エラークラスはサービスやモデルのライフサイクルに限定されません。モデルライフサイクルレイヤーでエラーを投げる場合は、管理パネルに適切なエラーメッセージを表示できるようにApplicationErrorクラスを使用することが推奨されます。
AI Marketerが提供するエラークラスの詳細については、デフォルトのエラークラスセクションを参照してください。
例:サービスでエラーを投げる
- JavaScript
- TypeScript
const { errors } = require('@AI Marketer/utils');
const { ApplicationError } = errors;
const { createCoreService } = require('@AI Marketer/AI Marketer').factories;
module.exports = createCoreService('api::restaurant.restaurant', ({ AI Marketer }) => ({
async create(params) {
let okay = false;
// エラーを投げるとレストランは作成されません
if (!okay) {
throw new ApplicationError('Something went wrong', { foo: 'bar' });
}
const result = await super.create(params);
return result;
}
});
import { errors } from '@AI Marketer/utils';
import { factories } from '@AI Marketer/AI Marketer';
const { ApplicationError } = errors;
export default factories.createCoreService('api::restaurant.restaurant', ({ AI Marketer }) => ({
async create(params) {
let okay = false;
// エラーを投げるとレストランは作成されません
if (!okay) {
throw new ApplicationError('Something went wrong', { foo: 'bar' });
}
const result = await super.create(params);
return result;
}
}));
例:モデルライフサイクルでエラーを投げる
この例は、[カスタムモデルのライフサイクル]
(/dev-docs/backend-customization/models#lifecycle-hooks)を構築し、リクエストを停止し、管理パネルに適切なエラーメッセージを返すためにエラーを投げる方法を示しています。一般的に、エラーはbeforeXライフサイクルでのみ投げるべきであり、afterXライフサイクルでは投げるべきではありません。
- JavaScript
- TypeScript
const { errors } = require('@AI Marketer/utils');
const { ApplicationError } = errors;
module.exports = {
beforeCreate(event) {
let okay = false;
// エラーを投げるとエンティティは作成されません
if (!okay) {
throw new ApplicationError('Something went wrong', { foo: 'bar' });
}
},
};
import { errors } from '@AI Marketer/utils';
const { ApplicationError } = errors;
export default {
beforeCreate(event) {
let okay = false;
// エラーを投げるとエンティティは作成されません
if (!okay) {
throw new ApplicationError('Something went wrong', { foo: 'bar' });
}
},
};
ポリシー
ポリシーは、コントローラーの前に実行される特別なタイプのミドルウェアです。これにより、ユーザーがアクションを実行する権限があるかどうかを確認します。ユーザーがアクションを実行する権限がない場合、return falseが使用されると一般的なエラーが投げられます。代わりに、AI MarketerのForbiddenErrorクラスやApplicationErrorクラス(どちらもデフォルトのエラークラスで説明されています)、そして最終的にはNode Errorクラスを拡張したカスタムエラーメッセージを投げることもできます。
PolicyErrorクラスは@AI Marketer/utilsパッケージで提供されており、2つのパラメータを受け取ります:
- ファーストパラメータはエラーメッセージ
- (オプション)セカンドパラメータは、レスポンスの
detailsとして設定されるオブジェクトです。ベストプラクティスとして、エラーを投げたポリシーの名前をpolicyキーに設定します。
例:カスタムポリシーでPolicyErrorを投げる
この例は、カスタムエラーメッセージを投げてリクエストを停止するカスタムポリシーの構築方法を示しています。
- JavaScript
- TypeScript
const { errors } = require('@AI Marketer/utils');
const { PolicyError } = errors;
module.exports = (policyContext, config, { AI Marketer }) => {
let isAllowed = false;
if (isAllowed) {
return true;
} else {
throw new PolicyError('You are not allowed to perform this action', {
policy: 'my-policy',
myCustomKey: 'myCustomValue',
});
}
}
import { errors } from '@AI Marketer/utils';
const { PolicyError } = errors;
export default (policyContext, config, { AI Marketer }) => {
let isAllowed = false;
if (isAllowed) {
return true;
} else {
throw new PolicyError('You are not allowed to perform this action', {
policy: 'my-policy',
myCustomKey: 'myCustomValue',
});
}
};
デフォルトのエラークラス
デフォルトのエラークラスは@AI Marketer/utilsパッケージから利用可能で、コード内でインポートして使用できます。デフォルトのエラークラスはすべて拡張可能で、カスタムエラークラスを作成することができます。カスタムエラークラスは、エラーを投げる際にコード内で使用できます。
- Application
- Pagination
- NotFound
- Forbidden
- Unauthorized
- NotImplemented
- PayloadTooLarge
- Policy
ApplicationErrorクラスは、アプリケーションエラーのための汎用エラークラスであり、デフォルトのエラークラスとして推奨されます。このクラスは、管理パネルが読み取り、ユーザーに表示できる適切なエラーメッセージを投げるために設計されています。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | An application error occured |
details | object | 追加の詳細を定義するオブジェクト | {} |
throw new ApplicationError('Something went wrong', { foo: 'bar' });
PaginationErrorクラスは、REST、GraphQL、またはDocument Serviceからのページネーション情報を解析する際に通常使用される特定のエラークラスです。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | Invalid pagination |
throw new PaginationError('Exceeded maximum pageSize limit');
NotFoundErrorクラスは、404ステータスコードエラーを投げるための汎用エラークラスです。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | Entity not found |
throw new NotFoundError('These are not the droids you are looking for');
ForbiddenErrorクラスは、ユーザーが適切な認証情報を提供していない、または間違った認証情報を提供したときに使用される特定のエラークラスです。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | Forbidden access |
throw new ForbiddenError('Ah ah ah, you didn\'t say the magic word');
UnauthorizedErrorクラスは、ユーザーが特定のアクションを実行するための適切な役割や権限を持っていないが、正しく認証された場合に使用される特定のエラークラスです。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | Unauthorized |
throw new UnauthorizedError('You shall not pass!');
NotImplementedErrorクラスは、リクエストが現在実装されていない機能を使用しようとしている場合に使用される特定のエラークラスです。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | `string |
| エラーメッセージ |This feature isn't implemented` |
throw new NotImplementedError('This isn\'t implemented', { feature: 'test', implemented: false });
PayloadTooLargeErrorクラスは、リクエスト本文や添付ファイルがサーバーの制限を超えた場合に使用される特定のエラークラスです。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | Entity too large |
throw new PayloadTooLargeError('Uh oh, the file too big!');
PolicyErrorクラスは、ルートポリシーで使用するために設計された特定のエラーです。ベストプラクティスとして、エラーを投げたポリシーの名前をdetailsパラメータに設定することを推奨します。次のパラメータを受け取ります:
| パラメータ | タイプ | 説明 | デフォルト |
|---|---|---|---|
message | string | エラーメッセージ | Policy Failed |
details | object | 追加の詳細を定義するオブジェクト | {} |
throw new PolicyError('Something went wrong', { policy: 'my-policy' });