m13-domain-error
ドメインエラー発生時の分類や回復戦略、再試行、代替処理、エラーコード設計などを考慮し、システム全体の安定性とユーザー体験を向上させるエラー処理設計を支援するSkill。
📜 元の英語説明(参考)
Use when designing domain error handling. Keywords: domain error, error categorization, recovery strategy, retry, fallback, domain error hierarchy, user-facing vs internal errors, error code design, circuit breaker, graceful degradation, resilience, error context, backoff, retry with backoff, error recovery, transient vs permanent error, 领域错误, 错误分类, 恢复策略, 重试, 熔断器, 优雅降级
🇯🇵 日本人クリエイター向け解説
ドメインエラー発生時の分類や回復戦略、再試行、代替処理、エラーコード設計などを考慮し、システム全体の安定性とユーザー体験を向上させるエラー処理設計を支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o m13-domain-error.zip https://jpskill.com/download/9271.zip && unzip -o m13-domain-error.zip && rm m13-domain-error.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9271.zip -OutFile "$d\m13-domain-error.zip"; Expand-Archive "$d\m13-domain-error.zip" -DestinationPath $d -Force; ri "$d\m13-domain-error.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
m13-domain-error.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
m13-domain-errorフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
ドメインエラー戦略
レイヤー2: 設計上の選択
中核となる質問
誰がこのエラーを処理する必要があり、どのように回復すべきか?
エラーの種類を設計する前に:
- これはユーザー向けですか、それとも内部向けですか?
- 回復は可能ですか?
- デバッグにはどのようなコンテキストが必要ですか?
エラーの分類
| エラーの種類 | 対象者 | 回復 | 例 |
|---|---|---|---|
| ユーザー向け | エンドユーザー | 行動を促す | InvalidEmail、NotFound |
| 内部向け | 開発者 | デバッグ情報 | DatabaseError、ParseError |
| システム | Ops/SRE | 監視/アラート | ConnectionTimeout、RateLimited |
| 一時的 | 自動化 | リトライ | NetworkError、ServiceUnavailable |
| 永続的 | 人間 | 調査 | ConfigInvalid、DataCorrupted |
思考を促すプロンプト
エラーの種類を設計する前に:
-
誰がこのエラーを見るのか?
- エンドユーザー → フレンドリーなメッセージ、実行可能なアクション
- 開発者 → 詳細、デバッグ可能
- Ops → 構造化、アラート可能
-
回復できますか?
- 一時的 → バックオフ付きでリトライ
- 劣化可能 → フォールバック値
- 永続的 → フェイルファスト、アラート
-
どのようなコンテキストが必要ですか?
- 呼び出しチェーン → anyhow::Context
- リクエストID → 構造化ロギング
- 入力データ → エラーペイロード
上方向へのトレース ↑
ドメイン制約(レイヤー3)へ:
「支払いの失敗をどのように処理すべきか?」
↑ 質問: リトライに関するビジネスルールは何ですか?
↑ 確認: domain-fintech (トランザクション要件)
↑ 確認: SLA (可用性要件)
| 質問 | トレース先 | 質問 |
|---|---|---|
| リトライポリシー | domain-* | リトライに許容されるレイテンシは? |
| ユーザーエクスペリエンス | domain-* | ユーザーにどのようなメッセージを表示すべきか? |
| コンプライアンス | domain-* | 監査のために何をログに記録する必要があるか? |
下方向へのトレース ↓
実装(レイヤー1)へ:
「型付きエラーが必要」
↓ m06-error-handling: ライブラリのための thiserror
↓ m04-zero-cost: Error enum の設計
「エラーコンテキストが必要」
↓ m06-error-handling: anyhow::Context
↓ ロギング: フィールド付きの tracing
「リトライロジックが必要」
↓ m07-concurrency: async リトライパターン
↓ クレート: tokio-retry, backoff
クイックリファレンス
| 回復パターン | いつ | 実装 |
|---|---|---|
| リトライ | 一時的な失敗 | 指数バックオフ |
| フォールバック | 劣化モード | キャッシュされた/デフォルト値 |
| サーキットブレーカー | カスケード障害 | failsafe-rs |
| タイムアウト | 遅い操作 | tokio::time::timeout |
| バルクヘッド | 分離 | 別のスレッドプール |
エラー階層
#[derive(thiserror::Error, Debug)]
pub enum AppError {
// ユーザー向け
#[error("Invalid input: {0}")]
Validation(String),
// 一時的 (リトライ可能)
#[error("Service temporarily unavailable")]
ServiceUnavailable(#[source] reqwest::Error),
// 内部 (詳細をログに記録、汎用的なものを表示)
#[error("Internal error")]
Internal(#[source] anyhow::Error),
}
impl AppError {
pub fn is_retryable(&self) -> bool {
matches!(self, Self::ServiceUnavailable(_))
}
}
リトライパターン
use tokio_retry::{Retry, strategy::ExponentialBackoff};
async fn with_retry<F, T, E>(f: F) -> Result<T, E>
where
F: Fn() -> impl Future<Output = Result<T, E>>,
E: std::fmt::Debug,
{
let strategy = ExponentialBackoff::from_millis(100)
.max_delay(Duration::from_secs(10))
.take(5);
Retry::spawn(strategy, || f()).await
}
よくある間違い
| 間違い | なぜ間違っているのか | より良い方法 |
|---|---|---|
| すべてに同じエラー | 行動可能性がない | 対象者別に分類する |
| すべてをリトライ | リソースの浪費 | 一時的なエラーのみ |
| 無限リトライ | 自己DoS | 最大試行回数 + バックオフ |
| 内部エラーを公開 | セキュリティリスク | ユーザーフレンドリーなメッセージ |
| コンテキストがない | デバッグが難しい | .context() を至る所で使用 |
アンチパターン
| アンチパターン | なぜ悪いのか | より良い方法 |
|---|---|---|
| String エラー | 構造がない | thiserror の型 |
| 回復可能なものに panic! | 悪いUX | コンテキスト付きの Result |
| エラーを無視 | サイレントな失敗 | ログに記録または伝播 |
| Box<dyn Error> を至る所に | 型情報が失われる | thiserror |
| ハッピーパスでのエラー | パフォーマンス | 事前検証 |
関連スキル
| いつ | 参照 |
|---|---|
| エラー処理の基本 | m06-error-handling |
| リトライの実装 | m07-concurrency |
| ドメインモデリング | m09-domain |
| ユーザー向けAPI | domain-* |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Domain Error Strategy
Layer 2: Design Choices
Core Question
Who needs to handle this error, and how should they recover?
Before designing error types:
- Is this user-facing or internal?
- Is recovery possible?
- What context is needed for debugging?
Error Categorization
| Error Type | Audience | Recovery | Example |
|---|---|---|---|
| User-facing | End users | Guide action | InvalidEmail, NotFound |
| Internal | Developers | Debug info | DatabaseError, ParseError |
| System | Ops/SRE | Monitor/alert | ConnectionTimeout, RateLimited |
| Transient | Automation | Retry | NetworkError, ServiceUnavailable |
| Permanent | Human | Investigate | ConfigInvalid, DataCorrupted |
Thinking Prompt
Before designing error types:
-
Who sees this error?
- End user → friendly message, actionable
- Developer → detailed, debuggable
- Ops → structured, alertable
-
Can we recover?
- Transient → retry with backoff
- Degradable → fallback value
- Permanent → fail fast, alert
-
What context is needed?
- Call chain → anyhow::Context
- Request ID → structured logging
- Input data → error payload
Trace Up ↑
To domain constraints (Layer 3):
"How should I handle payment failures?"
↑ Ask: What are the business rules for retries?
↑ Check: domain-fintech (transaction requirements)
↑ Check: SLA (availability requirements)
| Question | Trace To | Ask |
|---|---|---|
| Retry policy | domain-* | What's acceptable latency for retry? |
| User experience | domain-* | What message should users see? |
| Compliance | domain-* | What must be logged for audit? |
Trace Down ↓
To implementation (Layer 1):
"Need typed errors"
↓ m06-error-handling: thiserror for library
↓ m04-zero-cost: Error enum design
"Need error context"
↓ m06-error-handling: anyhow::Context
↓ Logging: tracing with fields
"Need retry logic"
↓ m07-concurrency: async retry patterns
↓ Crates: tokio-retry, backoff
Quick Reference
| Recovery Pattern | When | Implementation |
|---|---|---|
| Retry | Transient failures | exponential backoff |
| Fallback | Degraded mode | cached/default value |
| Circuit Breaker | Cascading failures | failsafe-rs |
| Timeout | Slow operations | tokio::time::timeout |
| Bulkhead | Isolation | separate thread pools |
Error Hierarchy
#[derive(thiserror::Error, Debug)]
pub enum AppError {
// User-facing
#[error("Invalid input: {0}")]
Validation(String),
// Transient (retryable)
#[error("Service temporarily unavailable")]
ServiceUnavailable(#[source] reqwest::Error),
// Internal (log details, show generic)
#[error("Internal error")]
Internal(#[source] anyhow::Error),
}
impl AppError {
pub fn is_retryable(&self) -> bool {
matches!(self, Self::ServiceUnavailable(_))
}
}
Retry Pattern
use tokio_retry::{Retry, strategy::ExponentialBackoff};
async fn with_retry<F, T, E>(f: F) -> Result<T, E>
where
F: Fn() -> impl Future<Output = Result<T, E>>,
E: std::fmt::Debug,
{
let strategy = ExponentialBackoff::from_millis(100)
.max_delay(Duration::from_secs(10))
.take(5);
Retry::spawn(strategy, || f()).await
}
Common Mistakes
| Mistake | Why Wrong | Better |
|---|---|---|
| Same error for all | No actionability | Categorize by audience |
| Retry everything | Wasted resources | Only transient errors |
| Infinite retry | DoS self | Max attempts + backoff |
| Expose internal errors | Security risk | User-friendly messages |
| No context | Hard to debug | .context() everywhere |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| String errors | No structure | thiserror types |
| panic! for recoverable | Bad UX | Result with context |
| Ignore errors | Silent failures | Log or propagate |
| Box<dyn Error> everywhere | Lost type info | thiserror |
| Error in happy path | Performance | Early validation |
Related Skills
| When | See |
|---|---|
| Error handling basics | m06-error-handling |
| Retry implementation | m07-concurrency |
| Domain modeling | m09-domain |
| User-facing APIs | domain-* |