Skip to main content

Error Message Documentation

This directory contains documentation for backend API error messages and guidelines for error handling.

Files

  • ERROR_SUMMARY.md — Executive summary with action items and implementation plan
  • ERROR_CATALOG.md — Complete catalog of all 75 HTTPException errors by category
  • error_catalog.json — Machine-readable format for tooling and automation

Quick Reference

Current State

  • 75 total HTTPException errors across 12 API modules
  • 40 (53%) are user-friendly
  • 35 (47%) use generic str(e) — need improvement

Priority Files to Fix

  1. backend/api/auth.py — 12 generic errors
  2. backend/api/members.py — 7 generic errors
  3. backend/api/groups.py — 3 generic errors
  4. backend/api/spaces.py — 3 generic errors
  5. backend/api/skills.py — 4 errors (2 generic + 2 wrong status codes)

Good Examples (Reference)

  • backend/api/chat.py — All 12 errors are user-friendly
  • backend/api/interfaces.py — All 9 errors include context
  • backend/api/oauth.py — Clear configuration/validation messages

Error Message Guidelines

✅ DO

# Specific, user-friendly message
raise HTTPException(
status_code=400,
detail="Space name must be unique within the group"
)

# Include context with dynamic values
raise HTTPException(
status_code=404,
detail=f"Interface not found: {interface_name}"
)

# Log full error for debugging (don't expose to user)
try:
await service.update(...)
except Exception as e:
logger.error(f"Update failed: {e}", exc_info=True)
raise HTTPException(
status_code=400,
detail="Unable to update. Please check your input and try again."
)

❌ DON'T

# Generic exception passthrough
raise HTTPException(status_code=400, detail=str(e))

# Exposing internal errors
raise HTTPException(
status_code=400,
detail=f"Invalid definition: {e}" # Exposes stack trace
)

# Wrong status code for business logic
raise HTTPException(
status_code=500,
detail="Failed to delete skill" # Should be 400
)

# Missing context
raise HTTPException(status_code=404, detail="Not found") # What's not found?

Status Code Guidelines

CodeUse CaseExample
400Bad Request — validation or business logic error"Space name must be unique"
401Unauthorized — authentication required or failed"Invalid email or password"
403Forbidden — authenticated but not permitted"Only group parents can cancel invites"
404Not Found — resource doesn't exist"Conversation not found"
409Conflict — duplicate resource"Skill 'daily_email' already exists"
422Unprocessable Entity — semantic validation error"Start date must be before end date"
500Internal Server Error — unexpected failureUse sparingly, log for investigation
502Bad Gateway — upstream service failed"Failed to connect to auth provider"

Error Response Format

Current (Simple String)

{
"detail": "Conversation not found"
}

Future (Structured with Codes)

{
"error": "CONVERSATION_NOT_FOUND",
"message": "The conversation you're looking for doesn't exist or has been deleted",
"code": "E404_CHAT_001",
"field": null
}

Implementation Roadmap

Phase 1: Foundation (Current Sprint — 3e.4)

  • Audit all HTTPException errors (ERROR_CATALOG.md)
  • Create backend/errors.py with message constants
  • Create backend/utils/error_handler.py for exception mapping
  • Update auth.py (12 errors)
  • Update members.py (7 errors)
  • Update groups.py, spaces.py, tasks.py, skills.py (10 errors)

Phase 2: Client-Side Improvements

  • Update frontend error interceptor
  • Add toast notifications for common errors
  • Test error display in all UI components

Phase 3: Structured Errors (Future)

  • Add error codes (E400_AUTH_001, etc.)
  • Support i18n for error messages
  • Document all error codes in docs/api.md

Testing

When updating error messages:

  1. Update tests — replace expected error text
  2. Test error display — verify frontend shows friendly message
  3. Check logs — ensure full error details are still logged
  4. Verify no PII — error messages must not expose personal data

Last Updated: 2026-02-13 Status: Phase 1 in progress (3e.4 — Engagement & Polish)