smithery/ricardoroche

structured-errors

Automatically applies when writing error handling in APIs and tools. Ensures errors are returned as structured JSON with error, request_id, and timestamp (not plain strings).

Installation

$ npx skills add smithery/ricardoroche --skill structured-errors

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/ricardoroche.

npx skills add smithery/ricardoroche

Browse all from smithery/ricardoroche

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,589 B
  • docs SUMMARY.md 199 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Structured Error Response Enforcer

When writing error handling in API endpoints, tools, or services, always return structured JSON errors.

✅ Correct Pattern

import uuid
from datetime import datetime
import json

def create_error_response(
    error_message: str,
    status_code: int = 500,
    details: dict = None
) -> dict:
    """Create structured error response."""
    response = {
        "error": error_message,
        "request_id": str(uuid.uuid4()),
        "timestamp": datetime.now().isoformat(),
        "status_code": status_code
    }
    if details:
        response["details"] = details
    return response

# In API endpoint
@app.get("/users/{user_id}")
async def get_user(user_id: str):
    if not user_id:
        raise HTTPException(
            status_code=400,
            detail=create_error_response(
                "User ID is required",
                status_code=400
            )
        )

    try:
        user = await fetch_user(user_id)
        return user
    except UserNotFoundError:
        raise HTTPException(
            status_code=404,
            detail=create_error_response(
                "User not found",
                status_code=404,
                details={"user_id": user_id}
            )
        )

# In tool function
def process_data(data: str) -> str:
    if not data:
        return json.dumps(create_error_response(
            "Data is required",
            status_code=400
        ))

    try:
        result = parse_data(data)
        return json.dumps({"result": result})
    except Exception as e:
        return json.dumps(create_error_response(
            "Failed to process data",
            status_code=500,
            details={"error_type": type(e).__name__}
        ))

❌ Incorrect Pattern

# ❌ Plain string
if not user_id:
    return "Error: user ID is required"

# ❌ Exposing sensitive data
except httpx.HTTPStatusError as e:
    return f"Error: {e.response.text}"  # ❌ Leaks API response

# ❌ No request ID for tracing
return {"error": "Something went wrong"}

# ❌ Inconsistent error format
return "Error: failed"  # Sometimes string
return {"message": "failed"}  # Sometimes object

Required Fields

All error responses must include:

  1. error (string) - Human-readable error message
  2. request_id (uuid) - For tracing/debugging
  3. timestamp (ISO string) - When error occurred
  4. status_code (int) - HTTP status code

Optional but recommended:

  1. details (object) - Additional context (safe data only)
  2. error_code (string) - Application-specific error code
  3. field (string) - Which field caused the error (validation)

Custom Exception Classes

class APIError(Exception):
    """Base exception for API errors."""

    def __init__(self, message: str, status_code: int = 500, details: dict = None):
        self.message = message
        self.status_code = status_code
        self.details = details or {}
        self.request_id = str(uuid.uuid4())
        self.timestamp = datetime.now().isoformat()
        super().__init__(self.message)

    def to_dict(self) -> dict:
        """Convert to structured error response."""
        return {
            "error": self.message,
            "status_code": self.status_code,
            "request_id": self.request_id,
            "timestamp": self.timestamp,
            "details": self.details
        }

class ValidationError(APIError):
    """Validation error."""
    def __init__(self, message: str, field: str = None):
        details = {"field": field} if field else {}
        super().__init__(message, status_code=400, details=details)

class NotFoundError(APIError):
    """Resource not found."""
    def __init__(self, resource: str, resource_id: str):
        super().__init__(
            f"{resource} not found",
            status_code=404,
            details={"resource": resource, "id": resource_id}
        )

# Usage
try:
    user = await get_user(user_id)
except UserNotFoundError:
    raise NotFoundError("User", user_id)

FastAPI Integration

from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.exception_handler(APIError)
async def api_error_handler(request: Request, exc: APIError):
    """Global exception handler for APIError."""
    return JSONResponse(
        status_code=exc.status_code,
        content=exc.to_dict()
    )

@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
    """Catch-all for unexpected errors."""
    error_response = create_error_response(
        "Internal server error",
        status_code=500,
        details={"type": type(exc).__name__}
    )
    # Log full error but don't expose to client
    logger.error(f"Unexpected error: {exc}", exc_info=True)
    return JSONResponse(status_code=500, content=error_response)

Security Note

Never include in errors:

  • Raw API response text
  • Stack traces (log them, don't return them)
  • Internal IDs or tokens
  • Database query details
  • Full exception messages from external APIs
  • Authentication credentials
  • File paths or system information

Safe to include:

  • User-facing error messages
  • Validation field names
  • Request IDs for support
  • Status codes
  • Generic error types

Logging Errors

import logging

logger = logging.getLogger(__name__)

def handle_error(error: Exception, context: dict = None) -> dict:
    """Handle error with proper logging and structured response."""
    request_id = str(uuid.uuid4())

    # Log with context
    logger.error(
        f"Error occurred | request_id={request_id} | "
        f"error={type(error).__name__}",
        extra=context,
        exc_info=True
    )

    # Return safe error response
    return create_error_response(
        "An error occurred processing your request",
        status_code=500,
        details={"request_id": request_id}
    )

❌ Anti-Patterns

# ❌ Leaking internal errors
return {"error": str(exception)}

# ❌ Inconsistent format across endpoints
def endpoint1(): return "Error"
def endpoint2(): return {"error": "Error"}

# ❌ No context for debugging
return {"error": "Failed"}

# ❌ Returning 200 with error in body
return {"success": False, "error": "..."}  # Should use proper status code

# ❌ Too much information
return {
    "error": f"Database query failed: {full_sql_query}",
    "stacktrace": traceback.format_exc()
}

Best Practices Checklist

  • ✅ Use consistent error structure across application
  • ✅ Include request_id for tracing
  • ✅ Include timestamp for debugging
  • ✅ Use proper HTTP status codes
  • ✅ Create custom exception classes for common errors
  • ✅ Add global exception handlers
  • ✅ Log full error details (with context)
  • ✅ Return safe, user-friendly messages
  • ✅ Never expose sensitive data in errors
  • ✅ Document error responses in API docs

Auto-Apply

When you write error handling:

  1. Create helper createerrorresponse()
  2. Use it for all error returns
  3. Include request_id and timestamp
  4. Remove any sensitive data
  5. Use proper status codes

Related Skills

  • docstring-format - Document Raises section
  • pii-redaction - Redact PII in error logs
  • pydantic-models - For error response models