Patterns de conception de gestion d'erreurs avec Claude Code
Découvrez patterns de conception de gestion d'erreurs avec Claude Code. Conseils pratiques et exemples de code inclus.
エラーハンドリングの設計をClaude Codeで改善する
適切なエラーハンドリングはアプリケーションの堅牢性に直結します。Claude Codeを使えば、型安全で一貫性のあるエラーハンドリングパターンを効率的に実装できます。
カスタムエラークラスの設計
> アプリケーション全体で使うカスタムエラークラスを設計して。
> HTTPステータスコードとの対応、エラーコード、
> ユーザー向けメッセージを含めて。
// errors/base.ts
export abstract class AppError extends Error {
abstract readonly statusCode: number;
abstract readonly code: string;
readonly isOperational: boolean;
constructor(message: string, isOperational = true) {
super(message);
this.name = this.constructor.name;
this.isOperational = isOperational;
Error.captureStackTrace(this, this.constructor);
}
toJSON() {
return {
error: {
code: this.code,
message: this.message,
...(process.env.NODE_ENV === "development" && { stack: this.stack }),
},
};
}
}
// errors/http.ts
export class NotFoundError extends AppError {
readonly statusCode = 404;
readonly code = "NOT_FOUND";
constructor(resource: string, id?: string) {
super(id ? `${resource}(${id})が見つかりません` : `${resource}が見つかりません`);
}
}
export class ValidationError extends AppError {
readonly statusCode = 400;
readonly code = "VALIDATION_ERROR";
readonly fields: Record<string, string[]>;
constructor(fields: Record<string, string[]>) {
super("バリデーションエラーがあります");
this.fields = fields;
}
toJSON() {
return {
error: {
code: this.code,
message: this.message,
fields: this.fields,
},
};
}
}
export class UnauthorizedError extends AppError {
readonly statusCode = 401;
readonly code = "UNAUTHORIZED";
constructor(message = "Authentication required") {
super(message);
}
}
export class ForbiddenError extends AppError {
readonly statusCode = 403;
readonly code = "FORBIDDEN";
constructor(message = "権限がありません") {
super(message);
}
}
Result型パターン
例外を使わずにエラーを型安全に扱うResult型パターンです。
> Result型パターンを実装して。
> 成功と失敗を型レベルで区別できるように。
// types/result.ts
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function ok<T>(data: T): Result<T, never> {
return { success: true, data };
}
function err<E>(error: E): Result<never, E> {
return { success: false, error };
}
// Usage example
async function findUser(id: string): Promise<Result<User, NotFoundError>> {
const user = await db.user.findUnique({ where: { id } });
if (!user) {
return err(new NotFoundError("User", id));
}
return ok(user);
}
// 呼び出し側
const result = await findUser("123");
if (result.success) {
console.log(result.data.name); // 型安全にアクセス
} else {
console.log(result.error.message); // エラー型も型安全
}
グローバルエラーハンドラー
Express用のグローバルエラーハンドラーを実装します。
> Expressのグローバルエラーハンドラーミドルウェアを作成して。
> AppErrorは適切なレスポンスに変換、予期しないエラーは500に。
> 本番環境ではスタックトレースを隠す。
import { Request, Response, NextFunction } from "express";
import { AppError } from "../errors/base";
export function globalErrorHandler(
err: Error,
req: Request,
res: Response,
_next: NextFunction
) {
// ログ出力
if (err instanceof AppError && err.isOperational) {
console.warn(`[${err.code}] ${err.message}`);
} else {
console.error("Unexpected error:", err);
}
// AppErrorの場合は定義されたレスポンスを返す
if (err instanceof AppError) {
return res.status(err.statusCode).json(err.toJSON());
}
// 予期しないエラー
res.status(500).json({
error: {
code: "INTERNAL_ERROR",
message: process.env.NODE_ENV === "production"
? "サーバーエラーが発生しました"
: err.message,
},
});
}
非同期エラーのキャッチ
> Express のasync route handlerのエラーを
> 自動キャッチするラッパーを作成して。
import { Request, Response, NextFunction, RequestHandler } from "express";
function asyncHandler(
fn: (req: Request, res: Response, next: NextFunction) => Promise<void>
): RequestHandler {
return (req, res, next) => {
fn(req, res, next).catch(next);
};
}
// Usage example:try-catchが不要に
router.get("/users/:id", asyncHandler(async (req, res) => {
const user = await userService.findById(req.params.id);
if (!user) {
throw new NotFoundError("User", req.params.id);
}
res.json({ data: user });
}));
フロントエンドのエラーバウンダリ
> React Error Boundary を作成して。
> エラーの種類に応じて異なるUIを表示して。
import { Component, ReactNode } from "react";
interface Props {
children: ReactNode;
fallback?: (error: Error, retry: () => void) => ReactNode;
}
interface State {
error: Error | null;
}
class ErrorBoundary extends Component<Props, State> {
state: State = { error: null };
static getDerivedStateFromError(error: Error) {
return { error };
}
handleRetry = () => {
this.setState({ error: null });
};
render() {
if (this.state.error) {
if (this.props.fallback) {
return this.props.fallback(this.state.error, this.handleRetry);
}
return (
<div className="p-8 text-center">
<h2 className="text-xl font-bold text-red-600">エラーが発生しました</h2>
<p className="mt-2 text-gray-600">{this.state.error.message}</p>
<button
onClick={this.handleRetry}
className="mt-4 rounded bg-blue-500 px-4 py-2 text-white"
>
再試行
</button>
</div>
);
}
return this.props.children;
}
}
デバッグとエラー調査の具体的な方法はデバッグテクニック完全ガイドを、TypeScriptでの型設計はTypeScript開発での活用法を参照してください。セキュリティの観点からのエラー情報の扱い方はセキュリティ監査の自動化もあわせてご覧ください。
Summary
一貫したエラーハンドリング設計により、アプリケーションの堅牢性と保守性が大幅に向上します。Claude Codeを使えば、カスタムエラークラス、Result型、グローバルハンドラーを効率的に実装できます。
エラーハンドリングのベストプラクティスはNode.js公式ガイド、Claude CodeについてはAnthropic公式ドキュメントを参照してください。
Related Posts
Maîtriser les Hooks de Claude Code : Formatage automatique, tests automatiques et plus encore
Apprenez à configurer le formatage et les tests automatiques avec les hooks de Claude Code. Inclut des exemples de configuration pratiques et des cas d'utilisation concrets.
Configuration des serveurs MCP dans Claude Code et cas d'utilisation pratiques
Un guide complet sur les capacités des serveurs MCP de Claude Code. Apprenez à connecter des outils externes, configurer des serveurs et découvrez des exemples d'intégration concrets.
Le guide complet pour rédiger un CLAUDE.md : Bonnes pratiques de configuration de projet
Un guide approfondi pour rédiger des fichiers CLAUDE.md efficaces. Apprenez à communiquer votre stack technologique, vos conventions et la structure de votre projet pour maximiser la qualité des réponses de Claude Code.