jpskill.com
💼 ビジネス コミュニティ

error-handling-fundamentals

try/catch処理、APIエラー対応、非同期処理、ユーザーフィードバックなど、エラーが発生しやすい箇所をチェックし、システムがスムーズに動き続け、分かりやすいエラーメッセージを表示するように改善するSkill。

📜 元の英語説明(参考)

Auto-invoke when reviewing try/catch blocks, API error responses, async operations, or user feedback patterns. Enforces graceful degradation and meaningful error messages.

🇯🇵 日本人クリエイター向け解説

一言でいうと

try/catch処理、APIエラー対応、非同期処理、ユーザーフィードバックなど、エラーが発生しやすい箇所をチェックし、システムがスムーズに動き続け、分かりやすいエラーメッセージを表示するように改善するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o error-handling-fundamentals.zip https://jpskill.com/download/18281.zip && unzip -o error-handling-fundamentals.zip && rm error-handling-fundamentals.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/18281.zip -OutFile "$d\error-handling-fundamentals.zip"; Expand-Archive "$d\error-handling-fundamentals.zip" -DestinationPath $d -Force; ri "$d\error-handling-fundamentals.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して error-handling-fundamentals.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → error-handling-fundamentals フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

エラー処理の基礎レビュー

「エラーは失敗ではありません。情報です。価値のあるデータとして扱いましょう。」

適用するタイミング

以下のレビュー時にこのスキルを適用します。

  • try/catch ブロック
  • Promise チェーン (.then/.catch)
  • API エラーレスポンス
  • フォームのバリデーション
  • ネットワークリクエストの処理
  • ユーザー向けのエラーメッセージ

レビューチェックリスト

エラーキャッチ

  • [ ] 空の catch がないか: すべての catch ブロックが意味のある処理をしていますか?
  • [ ] 適切なスコープ: エラーは適切なレベルでキャッチされていますか?
  • [ ] コンテキストの追加: エラーには役立つデバッグ情報が含まれていますか?
  • [ ] finally の使用: クリーンアップ処理は finally ブロックに記述されていますか?

ユーザーエクスペリエンス

  • [ ] ユーザーフレンドリーなメッセージ: ユーザーはそのエラーを理解できますか?
  • [ ] 技術的な詳細の非表示: スタックトレースはユーザーに公開されていませんか?
  • [ ] 実行可能なフィードバック: エラーはユーザーに次に何をすべきかを伝えていますか?
  • [ ] グレースフルデグラデーション: エラーが発生してもアプリは部分的に動作しますか?

ロギングとデバッグ

  • [ ] エラーのログ: エラーはデバッグのために記録されていますか?
  • [ ] ログのコンテキスト: ログにはリクエスト ID、ユーザー ID などが含まれていますか?
  • [ ] 重要度レベル: 重大なエラーは警告と区別されていますか?

リカバリー

  • [ ] リトライロジック: この操作は失敗時にリトライすべきですか?
  • [ ] フォールバック値: エラー時に適切なデフォルト値はありますか?
  • [ ] ローディング状態: リトライ中にユーザーに通知されますか?

よくある間違い (アンチパターン)

1. 空の Catch (静かなる殺人者)

❌ try {
     await submitForm();
   } catch (error) {
     // TODO: 後で処理する (決して起こらない)
   }

✅ try {
     await submitForm();
   } catch (error) {
     console.error('Form submission failed:', error);
     setError('Could not submit. Please try again.');
   }

2. 早すぎる Catch

❌ function getUser(id) {
     try {
       return database.query(id);
     } catch {
       return null; // 呼び出し元は失敗したことに気づかない
     }
   }

✅ function getUser(id) {
     return database.query(id); // 呼び出し元に判断させる
   }

   // UI レイヤーで
   try {
     const user = await getUser(id);
   } catch (error) {
     showToast('Could not load user');
   }

3. 汎用的なエラーメッセージ

❌ catch (error) {
     setError('An error occurred');
   }

✅ catch (error) {
     if (error.code === 'NETWORK_ERROR') {
       setError('Check your internet connection');
     } else if (error.code === 'NOT_FOUND') {
       setError('User not found');
     } else {
       setError('Something went wrong. Please try again.');
     }
   }

4. スタックトレースのリーク

❌ res.status(500).json({
     error: error.message,
     stack: error.stack
   });

✅ logger.error('Request failed', { error, requestId });
   res.status(500).json({
     error: 'Something went wrong'
   });

5. finally の忘れ

❌ try {
     setLoading(true);
     await fetchData();
     setLoading(false);
   } catch (error) {
     handleError(error);
     // Loading が永遠に true のまま!
   }

✅ try {
     setLoading(true);
     await fetchData();
   } catch (error) {
     handleError(error);
   } finally {
     setLoading(false); // 常に実行される
   }

ソクラテス式質問

ジュニアに答えを与える代わりに、これらの質問をしてください。

  1. 空の Catch: 「これが何も言わずに失敗したらどうなりますか?」
  2. ユーザーメッセージ: 「あなたがユーザーなら、このメッセージは役に立ちますか?」
  3. リカバリー: 「これを自動的にリトライすべきですか?」
  4. スコープ: 「これはこのエラーをキャッチするのに適切な場所ですか?」
  5. ロギング: 「本番環境でこれをどのようにデバッグしますか?」

エラーメッセージのガイドライン

すること

  • 具体的にする: 「そのメールアドレスはすでに登録されています」
  • 役に立つようにする: 「インターネット接続を確認してください」
  • 次のステップを提供する: 「もう一度試してください」または「サポートに連絡してください」
  • 重要度を一致させる: 重大なエラーは警告よりも注意が必要です

しないこと

  • 技術的な詳細を表示する: TypeError: Cannot read property 'map' of undefined
  • 曖昧にする: 「エラーが発生しました」
  • ユーザーを責める: 「無効なデータを入力しました」
  • 専門用語を使う: 「HTTP 500 Internal Server Error」

エラー処理パターン

API/ネットワークエラー

async function fetchWithRetry(url: string, retries = 3): Promise<Response> {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    return response;
  } catch (error) {
    if (retries > 0) {
      await sleep(1000);
      return fetchWithRetry(url, retries - 1);
    }
    throw error;
  }
}

フォームのバリデーション

function validateForm(data: FormData) {
  const errors: Record<string, string> = {};

  if (!data.email) {
    errors.email = 'Email is required';
  } else if (!isValidEmail(data.email)) {
    errors.email = 'Please enter a valid email';
  }

  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
}

React エラー境界

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    logError(error, info);
  }

  render() {
    if (this.state.hasError) {
      return <FallbackUI />;
    }
    return this.props.children;
  }
}

標準リファレンス

詳細なパターンについては以下を参照してください。

  • /standards/global/error-handling.md

指摘すべき危険信号

フラグ 質問
空の catch ブロック 「これが失敗したらどうなりますか?」
catch (e) { return null } 「呼び出し元はどうやって失敗したことを知るのですか?」
ローディング状態がない 「ユーザーは待っている間何を見ますか?」
技術的なエラーが表示される 「ユーザーはこのメッセージを理解できますか?」
クリーンアップのための finally がない 「ローディング状態はエラー時にスタックしますか?」
console.log の代わりに error 「本番環境のログでこれをどのように見つけますか?」
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Error Handling Fundamentals Review

"Errors are not failures — they're information. Handle them like the valuable data they are."

When to Apply

Activate this skill when reviewing:

  • try/catch blocks
  • Promise chains (.then/.catch)
  • API error responses
  • Form validation
  • Network request handling
  • User-facing error messages

Review Checklist

Error Catching

  • [ ] No empty catches: Is every catch block doing something meaningful?
  • [ ] Proper scope: Are errors caught at the right level?
  • [ ] Context added: Do errors include helpful debugging info?
  • [ ] Finally used: Are cleanup operations in finally blocks?

User Experience

  • [ ] User-friendly messages: Will users understand the error?
  • [ ] No technical details exposed: Are stack traces hidden from users?
  • [ ] Actionable feedback: Does the error tell users what to do next?
  • [ ] Graceful degradation: Does the app still work partially on error?

Logging & Debugging

  • [ ] Errors logged: Are errors recorded for debugging?
  • [ ] Context in logs: Do logs include request ID, user ID, etc.?
  • [ ] Severity levels: Are critical errors distinguished from warnings?

Recovery

  • [ ] Retry logic: Should this operation retry on failure?
  • [ ] Fallback values: Is there a sensible default on error?
  • [ ] Loading states: Is the user informed while retrying?

Common Mistakes (Anti-Patterns)

1. The Empty Catch (The Silent Killer)

❌ try {
     await submitForm();
   } catch (error) {
     // TODO: handle later (never happens)
   }

✅ try {
     await submitForm();
   } catch (error) {
     console.error('Form submission failed:', error);
     setError('Could not submit. Please try again.');
   }

2. Catching Too Early

❌ function getUser(id) {
     try {
       return database.query(id);
     } catch {
       return null; // Caller has no idea it failed
     }
   }

✅ function getUser(id) {
     return database.query(id); // Let caller decide
   }

   // In UI layer
   try {
     const user = await getUser(id);
   } catch (error) {
     showToast('Could not load user');
   }

3. Generic Error Messages

❌ catch (error) {
     setError('An error occurred');
   }

✅ catch (error) {
     if (error.code === 'NETWORK_ERROR') {
       setError('Check your internet connection');
     } else if (error.code === 'NOT_FOUND') {
       setError('User not found');
     } else {
       setError('Something went wrong. Please try again.');
     }
   }

4. Leaking Stack Traces

❌ res.status(500).json({
     error: error.message,
     stack: error.stack
   });

✅ logger.error('Request failed', { error, requestId });
   res.status(500).json({
     error: 'Something went wrong'
   });

5. Forgetting Finally

❌ try {
     setLoading(true);
     await fetchData();
     setLoading(false);
   } catch (error) {
     handleError(error);
     // Loading stays true forever!
   }

✅ try {
     setLoading(true);
     await fetchData();
   } catch (error) {
     handleError(error);
   } finally {
     setLoading(false); // Always runs
   }

Socratic Questions

Ask the junior these questions instead of giving answers:

  1. Empty Catch: "What happens if this fails silently?"
  2. User Message: "If you were the user, would this message help you?"
  3. Recovery: "Should we retry this automatically?"
  4. Scope: "Is this the right place to catch this error?"
  5. Logging: "How will you debug this in production?"

Error Message Guidelines

Do

  • Be specific: "The email address is already registered"
  • Be helpful: "Please check your internet connection"
  • Offer next steps: "Try again" or "Contact support"
  • Match severity: Critical errors need more attention than warnings

Don't

  • Show technical details: TypeError: Cannot read property 'map' of undefined
  • Be vague: "An error occurred"
  • Blame the user: "You entered invalid data"
  • Use jargon: "HTTP 500 Internal Server Error"

Error Handling Patterns

API/Network Errors

async function fetchWithRetry(url: string, retries = 3): Promise<Response> {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    return response;
  } catch (error) {
    if (retries > 0) {
      await sleep(1000);
      return fetchWithRetry(url, retries - 1);
    }
    throw error;
  }
}

Form Validation

function validateForm(data: FormData) {
  const errors: Record<string, string> = {};

  if (!data.email) {
    errors.email = 'Email is required';
  } else if (!isValidEmail(data.email)) {
    errors.email = 'Please enter a valid email';
  }

  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
}

React Error Boundaries

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    logError(error, info);
  }

  render() {
    if (this.state.hasError) {
      return <FallbackUI />;
    }
    return this.props.children;
  }
}

Standards Reference

See detailed patterns in:

  • /standards/global/error-handling.md

Red Flags to Call Out

Flag Question to Ask
Empty catch block "What happens when this fails?"
catch (e) { return null } "How will the caller know it failed?"
No loading state "What does the user see while waiting?"
Technical error shown "Will the user understand this message?"
No finally for cleanup "Is loading state stuck on error?"
console.log instead of error "How will you find this in production logs?"