🚨 エラー処理
適切なエラー処理は、堅牢なバックエンドサービスを構築するために不可欠です。Nodeblocks SDKは、すべてのサービス間で一貫したユーザーフレンドリーなエラーレスポンスを保証する包括的なエラー処理パターンを提供します。
🎯 エラーレスポンス形式
すべてのNodeblocksサービスは、一貫したJSON形式でエラーを返します:
{
"error": {
"message": "エラーメッセージの説明",
"data": ["追加のエラー詳細"]
}
}
バリデーションエラー
リクエストのバリデーションが失敗した場合、追加の詳細が含まれます:
{
"error": {
"message": "バリデーションエラー",
"data": [
"request body must have required property 'name'",
"request body must have required property 'email'",
"request body must NOT have additional properties"
]
}
}
📋 一般的なエラーコード
400 Bad Request
- バリデーションエラー - 無効なリクエストボディ形式または必須フィールドの欠落
- Failed to create [entity] - データベース挿入操作が挿入されたIDを返さなかった
- Failed to update [entity] - 更新操作がデータを変更しない(変更が検出されない)
- Failed to delete [entity] - データベース削除操作が失敗した
401 Unauthorized
- token could not be verified - 認証トークンの欠落または無効
- Authentication failed - 認証トークンの欠落または無効
- Token fails security check - トークンのセキュリティバリデーションが失敗した
403 Forbidden
- User is not authorized to access this resource - ユーザーに必要な権限がない
- User is not authorized to access this [entity] - ユーザーに特定のエンティティ権限がない
404 Not Found
- [Entity] not found - リクエストされた操作に対してエンティティが存在しない
- [Entity] does not exist - リクエストされた操作に対してエンティティが存在しない
409 Conflict
- [Entity] already exists - 同じ識別子を持つエンティティが既に存在する
- User with this email already exists - 重複するユーザーメールアドレス
500 Internal Server Error
- Failed to create [entity] - データベース接続の問題または作成中の予期しない失敗
- Failed to get [entity] - データベース接続の問題または取得中の予期しない失敗
- Failed to find [entities] - データベース接続の問題、無効なフィルター構文、または一覧取得中の予期しない失敗
- Failed to update [entity] - データベース接続の問題または更新中の予期しない失敗
- Failed to delete [entity] - データベース接続の問題または削除中の予期しない失敗
🔧 サービス固有のエラーパターン
認証サービスエラー
{
"error": {
"message": "token could not be verified"
}
}
{
"error": {
"message": "Authentication failed"
}
}
ユーザーサービスエラー
{
"error": {
"message": "User profile not found"
}
}
{
"error": {
"message": "Identity is not authorized to access this resource"
}
}
組織サービスエラー
{
"error": {
"message": "Organization not found"
}
}
{
"error": {
"message": "Failed to create organization"
}
}
製品サービスエラー
{
"error": {
"message": "Product not found"
}
}
{
"error": {
"message": "Failed to create product"
}
}
カテゴリサービスエラー
{
"error": {
"message": "Category does not exist"
}
}
{
"error": {
"message": "Failed to create category"
}
}
属性サービスエラー
{
"error": {
"message": "Attribute group not found"
}
}
{
"error": {
"message": "Failed to create attribute group"
}
}
注文サービスエラー
{
"error": {
"message": "Order not found"
}
}
{
"error": {
"message": "Failed to create order"
}
}
チャットサービスエラー
{
"error": {
"message": "Channel not found"
}
}
{
"error": {
"message": "Chat message not found"
}
}
📐️ エラー処理のベストプラクティス
1. 一貫したエラーメッセージ
すべてのサービス間で一貫した、ユーザーフレンドリーなエラーメッセージを使用します:
// ✅ 良い: 明確で実行可能なエラーメッセージ
"User profile not found"
"Failed to create organization"
"バリデーションエラー"
// ❌ 避ける: 技術的または不明瞭なメッセージ
"Database connection failed"
"Internal server error"
"Something went wrong"
2. 適切なHTTPステータスコード
異なるエラータイプに適切なHTTPステータスコードを使用します:
- 400 - Bad Request(バリデーションエラー、欠落フィールド)
- 401 - Unauthorized(認証失敗)
- 403 - Forbidden(認可失敗)
- 404 - Not Found(エンティティが存在しない)
- 409 - Conflict(重複エンティティ)
- 500 - Internal Server Error(データベースの問題、予期しない失敗)
3. バリデーションエラーの詳細
data配列に特定のバリデーションエラーの詳細を含めます:
{
"error": {
"message": "バリデーションエラー",
"data": [
"request body must have required property 'name'",
"request body must have required property 'email'",
"request body must NOT have additional properties"
]
}
}
4. 認証エラー処理
バリデーターを使用して認証エラーを自動的に処理します:
import { primitives, validators } from '@nodeblocks/backend-sdk';
const { withRoute } = primitives;
const { isAuthenticated } = validators;
// バリデーターは適切なステータスコードでNodeblocksErrorを自動的にスローします
export const protectedRoute = withRoute({
method: 'GET',
path: '/protected',
validators: [isAuthenticated()], // 認証されていない場合は401をスロー
handler: protectedHandler,
});
ハンドラーまたはバリデーターでのカスタム認証チェックの場合:
import { primitives } from '@nodeblocks/backend-sdk';
const validateAuth = async (payload: primitives.RouteHandlerPayload) => {
const tokenInfo = await payload.context.authenticate(payload);
if (!tokenInfo) {
throw new primitives.NodeblocksError(
401,
'token could not be verified',
'validateAuth'
);
}
};
5. 認可エラー処理
認可チェックにバリデーターを使用します:
import { primitives, validators } from '@nodeblocks/backend-sdk';
const { withRoute } = primitives;
const { validateResourceAccess, checkIdentityType } = validators;
// アイデンティティタイプをチェック(例:管理者のみ)
export const adminRoute = withRoute({
method: 'GET',
path: '/admin',
validators: [
checkIdentityType(['admin']), // 管理者でない場合は403をスロー
],
handler: adminHandler,
});
// またはリソースアクセスをチェック
export const resourceRoute = withRoute({
method: 'GET',
path: '/resource/:id',
validators: [
validateResourceAccess(['admin', 'self']), // 認可されていない場合は403をスロー
],
handler: resourceHandler,
});
バリデーターでのカスタム認可の場合:
import { primitives } from '@nodeblocks/backend-sdk';
const checkAdminRole = async (payload: primitives.RouteHandlerPayload) => {
const identity = payload.context.data?.identity;
if (!identity || identity.typeId !== 'admin') {
throw new primitives.NodeblocksError(
403,
'User is not authorized to access this resource',
'checkAdminRole'
);
}
};
⚙️ エラーミドルウェアの設定
アプリケーション全体で一貫したエラー処理を確保するために、nodeBlocksErrorMiddlewareを使用します:
import express from 'express';
import { middlewares, services, drivers } from '@nodeblocks/backend-sdk';
const { nodeBlocksErrorMiddleware } = middlewares;
const { userService, organizationService } = services;
const { withMongo } = drivers;
const connectToDatabase = withMongo('mongodb://localhost:27017', 'dev', 'user', 'password');
express()
.use(userService({
...(await connectToDatabase('users')),
...(await connectToDatabase('identity'))
}))
.use(organizationService({
...(await connectToDatabase('organizations')),
...(await connectToDatabase('identity'))
}))
.use(nodeBlocksErrorMiddleware()) // 最後に配置する必要があります
.listen(8089, () => console.log('Server running'));
⚠️ 重要: すべてのエラーがJSONレスポンスとして適切にフォーマットされるように、ルートとサービスの後に
nodeBlocksErrorMiddleware()を必ず追加してください。
🔍 エラーのデバッグ
開発モード
開発モードでは、追加のエラー詳細が含まれる場合があります:
{
"error": {
"message": "Database connection failed",
"stack": "Error: Database connection failed\n at createUser...",
"data": {
"operation": "createUser",
"timestamp": "2024-05-28T09:41:22.552Z"
}
}
}
本番モード
本番環境では、基本的なエラー情報のみが返されます:
{
"error": {
"message": "Internal server error"
}
}