원클릭으로
error-recovery-skill
Handle errors gracefully with retry strategies and fallback patterns
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Handle errors gracefully with retry strategies and fallback patterns
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use this skill to generate well-branded interfaces and assets for OpenCompany (zeenie.ai), either for production or throwaway prototypes/mocks/etc. Contains essential design guidelines, colors, type, fonts, assets, and UI kit components for prototyping.
Launch Android applications by package name. Open any installed app programmatically.
Get list of installed Android applications with package names, versions, and metadata.
Control Android audio - get/set volume, mute/unmute for media, ringtone, notification, and call volumes.
Monitor Android device battery status, level, charging state, temperature, and health.
Control Android Bluetooth - enable, disable, get status, and list paired devices.
| name | error-recovery-skill |
| description | Handle errors gracefully with retry strategies and fallback patterns |
| allowed-tools | delegate_to_ai_agent python_executor check_delegated_tasks |
| metadata | {"author":"opencompany","version":"1.0","category":"autonomous"} |
You are an agent that handles errors gracefully through retry strategies, alternative approaches, and graceful degradation.
┌─────────────────────────────────────────────────────────────┐
│ ERROR CATEGORIES │
├─────────────────────────────────────────────────────────────┤
│ │
│ TRANSIENT (Retry) RECOVERABLE (Alternative) │
│ ───────────────── ──────────────────────── │
│ • Network timeout • Missing data → try another │
│ • Rate limit (429) • Format error → parse differ │
│ • Service busy (503) • Partial failure → use partial │
│ • Connection reset • Auth expired → re-auth │
│ │
│ PERMANENT (Report) CRITICAL (Escalate) │
│ ────────────────── ─────────────────── │
│ • Not found (404) • Security violation │
│ • Permission denied (403) • Data corruption │
│ • Invalid input (400) • System failure │
│ • Resource deleted (410) • Unrecoverable state │
│ │
└─────────────────────────────────────────────────────────────┘
For transient errors, use exponential backoff:
┌─────────────────────────────────────────────────────────────┐
│ EXPONENTIAL BACKOFF │
├─────────────────────────────────────────────────────────────┤
│ │
│ Attempt 1 ──▶ FAIL ──▶ Wait 1 second │
│ │ │
│ ▼ │
│ Attempt 2 ──▶ FAIL ──▶ Wait 2 seconds │
│ │ │
│ ▼ │
│ Attempt 3 ──▶ FAIL ──▶ Wait 4 seconds │
│ │ │
│ ▼ │
│ Attempt 4 ──▶ FAIL ──▶ Report failure │
│ │
│ Formula: wait_time = 2^(attempt - 1) seconds │
│ Max attempts: 4 (configurable) │
│ │
└─────────────────────────────────────────────────────────────┘
import json
import time
def with_retry(operation, max_attempts=4):
"""Execute operation with exponential backoff retry."""
last_error = None
for attempt in range(1, max_attempts + 1):
try:
result = operation()
return {"success": True, "result": result, "attempts": attempt}
except Exception as e:
last_error = str(e)
# Check if error is retryable
if is_permanent_error(e):
return {
"success": False,
"error": last_error,
"error_type": "permanent",
"attempts": attempt
}
# Wait before retry (exponential backoff)
if attempt < max_attempts:
wait_time = 2 ** (attempt - 1)
time.sleep(wait_time)
return {
"success": False,
"error": last_error,
"error_type": "transient_exhausted",
"attempts": max_attempts
}
def is_permanent_error(e):
"""Check if error is permanent (should not retry)."""
error_msg = str(e).lower()
permanent_indicators = [
"not found", "404",
"permission denied", "403", "forbidden",
"invalid", "400", "bad request",
"unauthorized", "401"
]
return any(indicator in error_msg for indicator in permanent_indicators)
# Usage
result = with_retry(lambda: risky_operation())
print(json.dumps(result, indent=2))
When the primary approach fails, try alternatives:
┌─────────────────────────────────────────────────────────────┐
│ ALTERNATIVE APPROACHES │
├─────────────────────────────────────────────────────────────┤
│ │
│ Primary: API call to service A │
│ │ │
│ ▼ │
│ FAILED (service down) │
│ │ │
│ ▼ │
│ Alternative 1: Try service B (backup API) │
│ │ │
│ ▼ │
│ FAILED (rate limited) │
│ │ │
│ ▼ │
│ Alternative 2: Use cached data │
│ │ │
│ ▼ │
│ SUCCESS (stale but available) │
│ │ │
│ ▼ │
│ Return with warning: "Data may be outdated" │
│ │
└─────────────────────────────────────────────────────────────┘
Use delegation to retry with a different approach:
{
"task": "Retry: Get weather data using alternative source",
"context": "Attempt: 2/3
Error: Primary weather API timeout
Previous approach: OpenWeatherMap API
New approach: Try WeatherAPI.com or use cached forecast
Original request: Weather for New York"
}
When full success isn't possible, return partial results:
┌─────────────────────────────────────────────────────────────┐
│ GRACEFUL DEGRADATION │
├─────────────────────────────────────────────────────────────┤
│ │
│ Request: "Get user profile with posts and followers" │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Profile │ │ Posts │ │ Followers │ │
│ │ SUCCESS │ │ FAILED │ │ SUCCESS │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Response: │
│ { │
│ "profile": { ... }, // Full data │
│ "posts": null, // Unavailable │
│ "posts_error": "Service temporarily unavailable", │
│ "followers": [ ... ], // Full data │
│ "partial": true, // Indicates degraded response │
│ "degraded_fields": ["posts"] │
│ } │
│ │
└─────────────────────────────────────────────────────────────┘
import json
def fetch_user_data(user_id):
"""Fetch user data with graceful degradation."""
result = {
"user_id": user_id,
"partial": False,
"errors": []
}
# Try to get profile (required)
try:
result["profile"] = get_profile(user_id)
except Exception as e:
# Profile is required - cannot degrade
return {
"success": False,
"error": f"Cannot fetch required profile: {e}"
}
# Try to get posts (optional, can degrade)
try:
result["posts"] = get_posts(user_id)
except Exception as e:
result["posts"] = None
result["errors"].append(f"posts: {e}")
result["partial"] = True
# Try to get followers (optional, can degrade)
try:
result["followers"] = get_followers(user_id)
except Exception as e:
result["followers"] = None
result["errors"].append(f"followers: {e}")
result["partial"] = True
return {"success": True, "data": result}
# Simulated functions
def get_profile(uid): return {"name": "John", "email": "john@example.com"}
def get_posts(uid): raise Exception("Service unavailable")
def get_followers(uid): return [{"id": 1, "name": "Jane"}]
output = fetch_user_data("user_123")
print(json.dumps(output, indent=2))
When an iteration fails in an agentic loop:
┌─────────────────────────────────────────────────────────────┐
│ LOOP ERROR RECOVERY │
├─────────────────────────────────────────────────────────────┤
│ │
│ Iteration 2: FAILED │
│ │ │
│ ▼ │
│ Classify Error │
│ │ │
│ ├──▶ Transient? ──▶ Retry same iteration │
│ │ │
│ ├──▶ Recoverable? ──▶ Try alternative approach │
│ │ │
│ └──▶ Permanent? ──▶ Skip or report │
│ │
│ Continue to Iteration 3 with updated context: │
│ "Iteration 2 failed: [reason]. Proceeding with │
│ partial results from Iteration 1." │
│ │
└─────────────────────────────────────────────────────────────┘
{
"task": "Continue: Process remaining items (skip failed)",
"context": "Iteration: 3/5
Progress: Processed items 1-5, item 3 failed (invalid format)
State: Results for items [1,2,4,5] available
Error handling: Skipping item 3, continuing with remaining
Next: Process items 6-10"
}
┌─────────────────────────────────────────────────────────────┐
│ ERROR REPORT STRUCTURE │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. WHAT failed │
│ "Failed to send WhatsApp message" │
│ │
│ 2. WHY it failed │
│ "Recipient phone number not registered on WhatsApp" │
│ │
│ 3. WHAT was tried │
│ "Attempted 3 times with exponential backoff" │
│ │
│ 4. WHAT can be done │
│ "Try a different contact method (SMS, email) or │
│ verify the phone number is correct" │
│ │
│ 5. PARTIAL results (if any) │
│ "Message was prepared but not delivered" │
│ │
└─────────────────────────────────────────────────────────────┘
{
"success": false,
"error": {
"type": "delivery_failed",
"message": "Failed to send WhatsApp message",
"reason": "Recipient not on WhatsApp",
"attempts": 3,
"recovery_attempted": true,
"partial_result": {
"message_prepared": true,
"recipient_validated": false
}
},
"suggestions": [
"Verify the phone number format (+1234567890)",
"Try sending via SMS instead",
"Check if recipient has WhatsApp installed"
]
}
// Never do this
try:
result = risky_operation()
except:
pass // Error swallowed silently
// Always report
try:
result = risky_operation()
except Exception as e:
return {"success": False, "error": str(e)}
// Never do this
while True:
try:
result = operation()
break
except:
continue // Infinite loop
// Always limit attempts
for attempt in range(MAX_ATTEMPTS):
...
// Never retry these
- 404 Not Found
- 403 Forbidden
- 401 Unauthorized
- 400 Bad Request
// Only retry these
- 429 Too Many Requests
- 503 Service Unavailable
- 504 Gateway Timeout
- Connection errors
// Never do this
except Exception:
return "An error occurred"
// Preserve context
except Exception as e:
return f"Failed at step {step}: {e}. Progress: {progress}"