--- name: errors-confirmations description: This skill should be used when implementing graceful error handling and user confirmations in both backend and frontend, including friendly tool not found messages, action confirmations, error toasts, and loading indicators. --- # Errors & Confirmations Skill This skill provides guidance for implementing graceful error handling and user confirmations. ## Purpose Implement graceful errors in backend/frontend: - Tool not found → "Task not found, try again" - Always confirm actions in response (e.g., "Task added!") - Frontend: Show error toasts, loading indicators ## When to Use Use this skill when: - Building error handling for chat API - Creating user feedback mechanisms - Implementing loading states - Adding confirmation messages ## Capabilities - **Backend Errors**: Structured error responses with user-friendly messages - **Frontend Feedback**: Toast notifications, loading states - **Action Confirmations**: Clear success messages for user actions - **Error Recovery**: Graceful degradation and retry suggestions ## Backend Error Handling ### Error Response Models ```python from pydantic import BaseModel from typing import Optional, List from enum import Enum class ErrorSeverity(str, Enum): LOW = "low" MEDIUM = "medium" HIGH = "high" class ErrorResponse(BaseModel): success: bool = False error: str message: str # User-friendly message severity: ErrorSeverity = ErrorSeverity.MEDIUM retryable: bool = True suggestion: Optional[str] = None class ToolError(Exception): def __init__( self, message: str, user_message: str, severity: ErrorSeverity = ErrorSeverity.MEDIUM, retryable: bool = True, suggestion: Optional[str] = None ): self.message = message self.user_message = user_message self.severity = severity self.retryable = retryable self.suggestion = suggestion super().__init__(message) ``` ### Error Handlers ```python from fastapi import Request, HTTPException from fastapi.responses import JSONResponse @app.exception_handler(ToolError) async def tool_error_handler(request: Request, exc: ToolError): return JSONResponse( status_code=400 if exc.severity == ErrorSeverity.LOW else 500, content={ "success": False, "error": exc.message, "message": exc.user_message, "severity": exc.severity.value, "retryable": exc.retryable, "suggestion": exc.suggestion } ) @app.exception_handler(HTTPException) async def http_error_handler(request: Request, exc: HTTPException): user_messages = { 400: "There was an issue with your request. Please check and try again.", 401: "Please sign in to continue.", 403: "You don't have permission for this action.", 404: "The requested item was not found.", 500: "Something went wrong on our end. Please try again." } return JSONResponse( status_code=exc.status_code, content={ "success": False, "error": exc.detail, "message": user_messages.get(exc.status_code, "An error occurred"), "retryable": exc.status_code >= 500 } ) ``` ### Tool-Specific Errors ```python async def get_task_by_id(user_id: str, task_id: str) -> Task: """Get task with proper error handling.""" result = await session.execute( select(Task).where( Task.id == task_id, Task.user_id == user_id ) ) task = result.scalar_one_or_none() if not task: raise ToolError( message=f"Task {task_id} not found", user_message="I couldn't find that task. It may have been deleted already.", severity=ErrorSeverity.LOW, retryable=False, suggestion="Try listing your tasks to see what's available." ) return task async def add_task(user_id: str, title: str, **kwargs) -> dict: """Add task with confirmation.""" try: task = Task(user_id=user_id, title=title, **kwargs) session.add(task) await session.commit() await session.refresh(task) return { "success": True, "message": f"Task added successfully!", "task": task_to_dict(task) } except Exception as e: raise ToolError( message=f"Failed to add task: {str(e)}", user_message="I wasn't able to add that task. Please try again.", severity=ErrorSeverity.MEDIUM, retryable=True, suggestion="Check that the title isn't too long and try once more." ) ``` ## Frontend Error Handling ### Toast Notifications ```tsx // components/Toast.tsx interface ToastProps { message: string; type: "success" | "error" | "info" | "warning"; onClose: () => void; } export function Toast({ message, type, onClose }: ToastProps) { const styles = { success: "bg-green-500", error: "bg-red-500", info: "bg-blue-500", warning: "bg-yellow-500" }; return (
Please refresh the page and try again.