用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tomevault-io/skills-registry --skill error-handling-standards命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | error-handling-standards |
| description | >- Use when this capability is needed. |
サイレントエラーゼロトレランスを原則とし、すべてのエラーを適切に分類・処理・記録するためのスキル。 PATTERNS.md のセクション 3, 9 および FALLBACK.md で定義されたパターンを適用する。
以下のパターンはすべて禁止:
// ❌ 空の catch ブロック
try { doSomething(); } catch (e) {}
// ❌ console.log のみでエラーを握りつぶし
try { doSomething(); } catch (e) { console.log(e); }
// ❌ エラーを無視して null/undefined を返す
try { return fetchData(); } catch (e) { return null; }
// ❌ 汎用的すぎるエラーメッセージ
throw new Error('Something went wrong');
すべての catch ブロックは、エラーの記録、再スロー、またはResult.fail での返却のいずれかを行うこと。
例外: 環境分岐付きフォールバック(セクション8参照)は本番環境のみで許容される。無条件のフォールバックは禁止。
プロジェクトでは AppError を基底クラスとしたエラー階層を使用する:
// エラー基底クラス
abstract class AppError extends Error {
constructor(
public message: string,
public code: string,
public statusCode: number
) {
super(message);
this.name = this.constructor.name;
}
}
// バリデーションエラー
class ValidationError extends AppError {
constructor(message: string, public details: any[]) {
super(message, 'VALIDATION_ERROR', 400);
}
}
// リソース未検出エラー
class NotFoundError extends AppError {
constructor(message: string) {
super(message, 'NOT_FOUND', 404);
}
}
// 内部エラー
class InternalError extends AppError {
constructor(message: string) {
super(message, 'INTERNAL_ERROR', 500);
}
}
| エラークラス | エラーコード | HTTP ステータス | 用途 |
|---|---|---|---|
| ValidationError | VALIDATION_ERROR | 400 | 入力バリデーション失敗 |
| NotFoundError | NOT_FOUND | 404 | リソース未検出 |
| ForbiddenError | FORBIDDEN | 403 | 権限不足 |
| ConflictError | CONFLICT | 409 | 重複・競合 |
| InternalError | INTERNAL_ERROR | 500 | 予期しない内部エラー |
ForbiddenError と ConflictError は PATTERNS.md の基本階層には未定義だが、一般的な HTTP エラーとして推奨される拡張。 新しいエラー種別が必要な場合は、必ず AppError を継承して作成する。
ビジネスロジックでは例外スローではなく Result パターンを優先する:
// Result 型
type Result<T> = { ok: true; value: T } | { ok: false; error: AppError };
const Result = {
ok: <T>(value: T): Result<T> => ({ ok: true, value }),
fail: <T>(error: AppError): Result<T> => ({ ok: false, error }),
};
// 使用例
async function processUser(userId: string): Promise<Result<User>> {
try {
const user = await userRepository.findById(userId);
if (!user) {
return Result.fail(new NotFoundError('User not found'));
}
const processed = await processUserData(user);
return Result.ok(processed);
} catch (error) {
const err = error instanceof ? error : ((error));
logger.(, err, { userId });
(error ) {
.(error);
}
.( ());
}
}
Result パターンのメリット:
// ✅ 良い例: エラー型に応じた具体的な処理
try {
await riskyOperation();
} catch (error) {
if (error instanceof ValidationError) {
return Result.fail(error); // そのまま返却
}
if (error instanceof NotFoundError) {
logger.warn('Resource not found', { error });
return Result.fail(error);
}
// 未知のエラーは InternalError でラップ
logger.error('Unexpected error', { error });
return Result.fail(new InternalError('Unexpected error occurred'));
}
// ❌ 悪い例: 汎用的な catch のみ
try {
await riskyOperation();
} catch (error) {
throw new Error('Failed'); // 元のエラー情報が失われる
}
ルール:
instanceof でエラー型をチェックInternalError でラップして再スローエラーログは JSON 形式で構造化し、必要なコンテキストを含めること:
class Logger {
error(message: string, error: Error, meta?: Record<string, any>): void {
console.error(JSON.stringify({
level: 'error',
message,
error: {
name: error.name,
message: error.message,
stack: error.stack,
},
timestamp: new Date().toISOString(),
...meta,
}));
}
}
// 使用例
logger.error('Failed to process user', error, {
userId: '123',
operation: 'processUser',
requestId: req.headers['x-request-id'],
});
ログの必須フィールド:
level: エラーレベル(error / warn / info)message: 人間が読めるエラー説明error.name: エラークラス名error.message: エラーメッセージerror.stack: スタックトレースtimestamp: ISO 8601 形式禁止事項:
エラーハンドリングのコードレビュー時に確認する項目:
instanceof でエラー型をチェックしているかInternalError でラップされているか包括的なフォールバック戦略(階層モデル・レイヤー別パターン含む)は FALLBACK.md を参照。
AI(Claude Code, Copilot, Cursor等)は try-catch + デフォルト値返却を自動挿入する傾向がある。
このパターンは開発中のバグを隠蔽し、本番で初めて問題が発覚するリスクを生む。
// ❌ パターン1: 空 catch + デフォルト値
try { return await fetchData(); } catch { return defaultValue; }
// ❌ パターン2: エラー無視 + 空配列/空文字
try { return await getItems(); } catch { return []; }
// ❌ パターン3: catch 内で console.log のみ + フォールバック
try {
return await getData();
} catch (e) {
console.log(e);
return fallbackData;
}
// ❌ パターン4: Promise.catch() でサイレントフォールバック
const data = await fetchData().catch(() => defaultValue);
フォールバックが必要な場合は、fallbackInProdOnly() ユーティリティ(推奨)または環境分岐を使用する:
// ✅ 環境別フォールバック(FALLBACK.md 準拠)
try {
return await fetchData();
} catch (error) {
const normalizedError = error instanceof Error ? error : new Error(String(error));
logger.error('Failed to fetch data', normalizedError, { operation: 'fetchData' });
const env = process.env.NODE_ENV;
if (env === 'development' || env === 'test') {
throw normalizedError; // 開発時: バグを即座に検出
}
return defaultValue; // 本番時のみ: UX保護
}
| 状況 | 対応 |
|---|---|
| catch 内でデフォルト値を返している | 環境分岐を追加するよう指摘 |
.catch(() => default) パターン | try-catch + 環境分岐に書き換え |
| 認証/認可/バリデーション/データ整合性エラーにフォールバック | 環境問わずスローに修正 |
既に fallbackInProdOnly() または環境分岐あり | OK(ログ記録・エラー正規化を確認) |
| フォールバックが明示的にビジネス要件 | コメントで理由を明記させる |
Converted and distributed by TomeVault — claim your Tome and manage your conversions.