用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/lebiraja/skills4agents --skill agent-module-error-taxonomy-and-handling命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | agent-module-error-taxonomy-and-handling |
| description | Module: Error Taxonomy and Unified Handling Standard |
agent.module.error-taxonomy-and-handling1.0.0productionUse this module to standardize error handling across all backend services, APIs, and async workflows.
Apply when:
Do not apply directly when:
All errors fall into four mutually exclusive categories:
Cause: Client request is malformed, unauthorized, or violates constraints.
Client action: Fix request or escalate to operator; retrying without change is futile.
HTTP range: 400–499
Subcategories:
400) – Malformed payload, missing required fields, invalid formats.401) – Missing, expired, or invalid credentials.403) – Credentials valid but insufficient permissions.404) – Resource does not exist or access denied.409) – Business rule violation, duplicate, or state conflict.Cause: Temporary infrastructure, dependency, or resource exhaustion.
Client action: Retry with exponential backoff; likely to succeed on retry.
HTTP range: 500–599 (specific codes vary)
Subcategories:
503) – Dependency (DB, cache, external service) temporarily down.504) – Request exceeded deadline; likely transient.429) – Client quota/rate limit exceeded; back off and retry.Cause: Bug, configuration error, or permanent data inconsistency.
Client action: Do not retry; escalate to operator immediately.
HTTP range: 500 (with Retry-After: never or explicit non-retryable marker)
Subcategories:
500) – Unhandled exception, invariant violation, or data corruption.501) – Feature not available (API version mismatch, incomplete deployment).Cause: Job execution failure in queue/worker context. Retry behavior: Transient failures enter backoff queue; permanent failures escalate or dead-letter. Status codes: Job-specific status enum (not HTTP codes).
Every error must have a machine-readable code following the pattern:
<DOMAIN>_<ERROR_TYPE>_<SPECIFIC_REASON>
Examples:
AUTH_INVALID_TOKEN – Token format or signature invalidAUTH_TOKEN_EXPIRED – Token lifetime exceededAUTH_INSUFFICIENT_PERMISSIONS – Valid token lacks required scopeVALIDATION_EMAIL_FORMAT – Email field failed format checkVALIDATION_PHONE_E164 – Phone field failed E.164 validationRESOURCE_NOT_FOUND – Requested resource ID does not existCONFLICT_DUPLICATE_EMAIL – Email already registeredCONFLICT_STATE_TRANSITION – State change violates workflow rulesEXTERNAL_SERVICE_TIMEOUT – Third-party API did not respond in timeEXTERNAL_SERVICE_UNAVAILABLE – Third-party service is downRATE_LIMITED_BURST – Client exceeded request rateINTERNAL_DATABASE_ERROR – Database connection or query failure (permanent)INTERNAL_ASSERTION_FAILED – Code invariant violated (permanent)Domain prefixes (extensible):
AUTH – Authentication/authorizationVALIDATION – Input validationRESOURCE – Resource lifecycle and lookupCONFLICT – Business constraint and state machine violationsEXTERNAL – Third-party service failuresRATE_LIMIT – Quota/throttlingINTERNAL – Server-side bugs and invariantsEvery error code must be classified:
| Error Code | Category | HTTP Status | Retryable | Backoff Strategy |
|---|---|---|---|---|
AUTH_INVALID_TOKEN | Client | 401 | No | None |
AUTH_TOKEN_EXPIRED | Client | 401 | No | None |
VALIDATION_* | Client | 400 | No | None |
RESOURCE_NOT_FOUND | Client | 404 | No | None |
CONFLICT_* | Client | 409 | No | None |
RATE_LIMITED_BURST | Transient | 429 | Yes | Exponential with Retry-After |
EXTERNAL_SERVICE_TIMEOUT | Transient | 504 | Yes | Exponential (3 attempts, 1s–10s) |
EXTERNAL_SERVICE_UNAVAILABLE | Transient | 503 | Yes | Exponential with Retry-After |
INTERNAL_DATABASE_ERROR | Permanent | 500 | No | Alert operator |
INTERNAL_ASSERTION_FAILED | Permanent | 500 | No | Alert operator |
All 4xx and 5xx responses must conform to this structure:
{
"error": {
"code": "VALIDATION_EMAIL_FORMAT",
"message": "Email address is invalid.",
"http_status": 400,
"retryable": false,
"timestamp": "2026-04-04T12:34:56Z",
"correlation_id": "req-abc123def456",
"fields": [
{
"field_name": "email",
"rejected_value": "[REDACTED]",
"constraint_violated": "format"
}
],
"context": {
"endpoint": "/api/v1/users",
"user_id":
Field definitions:
code – Machine-readable error code (always present).message – Human-readable message safe for client display (no PII).http_status – HTTP status code (redundant with header but explicit in body).retryable – Boolean; client uses to decide retry logic.timestamp – ISO 8601 server timestamp for ordering.correlation_id – Unique request ID for log correlation.fields – Array of validation errors (present only for 400/422 validation failures).
field_name – Name of field that failed validation.rejected_value – Sanitized/redacted value (never raw user input if sensitive).constraint_violated – Machine code for which constraint failed (e.g., format, required, uniqueness).context – Optional operator context (endpoint, user_id, resource_id) for debugging; redacted in external-facing responses.HTTP/1.1 400 Bad Request
Content-Type: application/json
Correlation-ID: req-abc123def456
Retry-After: <not present for 400>
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Correlation-ID: req-abc123def456
Retry-After: 60
HTTP/1.1 503 Service Unavailable
Content-Type: application/json
Correlation-ID: req-abc123def456
Retry-After: 30
Example implementation (Python):
from enum import Enum
from dataclasses import dataclass
@dataclass
class ErrorDefinition:
code: str
message: str
http_status: int
retryable: bool
retry_backoff: str # "exponential", "fixed", or "none"
class ErrorRegistry:
VALIDATION_EMAIL_FORMAT = ErrorDefinition(
code="VALIDATION_EMAIL_FORMAT",
message="Email address is invalid.",
http_status=400,
retryable=False,
retry_backoff="none"
)
AUTH_TOKEN_EXPIRED = ErrorDefinition(
code="AUTH_TOKEN_EXPIRED",
message="Session expired. Please log in again.",
http_status=401,
retryable=False,
retry_backoff="none"
)
EXTERNAL_SERVICE_TIMEOUT = ErrorDefinition(
code="EXTERNAL_SERVICE_TIMEOUT",
message="Request timeout. Please try again.",
http_status=504,
retryable=True,
retry_backoff="exponential"
)
Exit criteria:
ErrorResponse class that constructs structured error payloads.Example:
from dataclasses import dataclass, asdict
from uuid import uuid4
from datetime import datetime
@dataclass
class FieldError:
field_name: str
rejected_value: str # sanitized
constraint_violated: str
@dataclass
class ErrorResponse:
code: str
message: str
http_status: int
retryable: bool
correlation_id: str
timestamp: str
fields: list[FieldError] = None
context: dict = None
@staticmethod
def from_registry(definition: ErrorDefinition, fields: list[FieldError] = None, context: dict = None):
return ErrorResponse(
code=definition.code,
message=definition.message,
http_status=definition.http_status,
retryable=definition.retryable,
correlation_id=str(uuid4()),
timestamp=datetime.utcnow().isoformat() + "Z",
fields=fields,
context=context
)
def to_dict(self, include_context: bool = False):
data = asdict(self)
if not include_context:
data.pop(, )
{: data}
Exit criteria:
ApplicationError.Example:
class ApplicationError(Exception):
def __init__(self, error_def: ErrorDefinition, fields: list[FieldError] = None, context: dict = None):
self.error_def = error_def
self.fields = fields
self.context = context
super().__init__(error_def.message)
class ValidationError(ApplicationError):
pass
class AuthenticationError(ApplicationError):
pass
class ExternalServiceError(ApplicationError):
pass
# FastAPI exception handler
@app.exception_handler(ApplicationError)
async def application_error_handler(request: Request, exc: ApplicationError):
# Log with full context
logger.error("Application error", extra={
"error_code": exc.error_def.code,
"path": request.url.path,
"fields": exc.fields,
"context": exc.context
})
response = ErrorResponse.from_registry(
exc.error_def,
fields=exc.fields,
context=exc.context if is_internal_request(request) else None
)
return JSONResponse(
status_code=exc.error_def.http_status,
content=response.to_dict()
)
Exit criteria:
Retry-After header and respect it.Example retry logic:
import asyncio
from typing import Callable, TypeVar
T = TypeVar('T')
async def retry_with_backoff(
func: Callable[[], T],
max_attempts: int = 3,
initial_delay: float = 1.0,
max_delay: float = 10.0,
jitter: bool = True
) -> T:
for attempt in range(max_attempts):
try:
return await func()
except ApplicationError as e:
if not e.error_def.retryable or attempt == max_attempts - 1:
raise
delay = min(initial_delay * (2 ** attempt), max_delay)
if jitter:
delay *= random.uniform(0.5, 1.0)
logger.warning(f"Retry attempt {attempt + 1}/{max_attempts} after {delay}s", extra={
"error_code": e.error_def.code,
"attempt": attempt + 1
})
await asyncio.sleep(delay)
Exit criteria:
Example runbook structure:
## Error: EXTERNAL_SERVICE_TIMEOUT
**Code:** `EXTERNAL_SERVICE_TIMEOUT`
**HTTP Status:** `504`
**Retryable:** Yes (exponential backoff, 3 attempts)
### Common Causes
- Third-party API service degradation or outage
- High network latency
- Client request timeout too tight for actual service latency
### Detection and Alerting
- Alert on 429 and 504 error rates > 1% for 5 minutes
- Check external service status page
- Correlate with network latency metrics
### Mitigation
1. Check third-party service status page
2. Increase request timeout temporarily (if safe)
3. Route to fallback service or graceful degradation
4. Page on-call if outage > 15 minutes
### Resolution Steps
- Wait for external service recovery (typical 5–30 min)
- Validate integrations after service is back up
- Run post-incident review if recurrence pattern detected
Exit criteria:
| Decision Area | Preferred Option | Alternative | Selection Rule |
|---|---|---|---|
| Error classification | Taxonomy with retryable flag | Enum with HTTP status only | Use taxonomy for client resilience and operator clarity. |
| Error response format | Structured JSON with code + message | Plain text message only | Use structured format for client parsing and logging. |
| Retry strategy | Exponential backoff with jitter | Fixed backoff or no backoff | Use exponential to avoid thundering herd. |
| Sensitive field exposure | Redacted/sanitized in response | Raw value in response | Always redact; server logs retain full context. |
| Operator context visibility | Include in logs, exclude from API response | Include in all responses | Prevent information leakage to untrusted clients. |
Retry-After header parsing and respect.100% for all 4xx/5xx responses100% of application exceptions>= 99.9% of requests0 per quarter<= 2 minutes100% in integration testsretryable flag and retry non-retryable errors.
This module is reusable across all backend services. Adapt only: