メインコンテンツまでスキップ
バージョン: 0.9.0 (最新)

🚨 エラー処理

適切なエラー処理は、堅牢なバックエンドサービスを構築するために不可欠です。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"
}
}