# Story 12.10: Exception Logging in FastAPI with request_id + Structured Context

**Status:** Complete
**Priority:** P2 (Medium)
**Depends on:** 12.1 (request_id concept)
**Epic:** 12.0 Cookbook (SEO-Driven Documentation)

---

## Context / Background

Unhandled exceptions in FastAPI often lose request context. The stack trace appears in logs, but without the request_id or other context that would help correlate it with the failing request. Developers ask "where do my errors go?" and "how do I attach request context to exceptions?"

fapilog's exception handler integration preserves request context in error logs.

**Target search queries:**

- "fastapi log unhandled exception request id"
- "fastapi exception handler logging"
- "python log exception with context"
- "correlate errors with requests fastapi"

**Why fapilog is the answer:** Automatic request context preservation in exception logs via middleware integration.

---

## Scope (In / Out)

### In Scope

- Cookbook page showing exception logging with context
- How request_id appears in error logs
- Custom exception handler integration
- Structured error fields

### Out of Scope

- Error monitoring services (Sentry, etc.)
- Custom exception classes
- Error response formatting

---

## Acceptance Criteria

### AC1: Page Exists with Correct Title

**Description:** Cookbook page created with SEO-optimized title.

**Validation:**
```
docs/cookbook/exception-logging-request-context.md exists
H1: "Exception logging in FastAPI with request_id + structured context"
```

### AC2: Problem Explained

**Description:** Why exceptions lose context.

**Validation:**
- Default exception handling loses request info
- Stack trace without correlation ID
- Example of the problem

### AC3: Automatic Context Shown

**Description:** How fapilog preserves context automatically.

**Validation:**
```python
# With fapilog setup, exceptions include request_id
from fapilog.fastapi import setup_logging

lifespan = setup_logging()
# Unhandled exceptions now logged with request context
```

Sample error log:
```json
{
  "level": "ERROR",
  "message": "ValueError: invalid input",
  "request_id": "abc-123",
  "path": "/api/users",
  "exception": { ... }
}
```

### AC4: Custom Exception Handler Pattern

**Description:** Integrating with custom exception handlers.

**Validation:**
```python
from fapilog.fastapi import get_request_logger

@app.exception_handler(CustomError)
async def handle_custom_error(request, exc):
    logger = get_request_logger(request)
    logger.error("Custom error", error=str(exc))
    return JSONResponse(...)
```

### AC5: Structured Error Fields Documented

**Description:** What fields appear in error logs.

**Validation:**
- exception_type
- exception_message
- stack_trace
- request context fields

---

## Implementation Notes

### File Path

`docs/cookbook/exception-logging-request-context.md`

### Page Structure

```markdown
# Exception logging in FastAPI with request_id + structured context

When your app crashes, you need to know which request caused it...

## The Problem: Lost Context in Errors

{Default behavior loses request info}
{Example stack trace without correlation}

## The Solution: Automatic Context Preservation

```python
lifespan = setup_logging()
```

{Sample structured error log}

## Custom Exception Handlers

{Integration pattern}

## Structured Error Fields

| Field | Description |
|-------|-------------|
| exception_type | Exception class name |
| exception_message | str(exception) |
| stack_trace | Full traceback |
| request_id | Correlation ID |
| path | Request path |

## Going Deeper

- [Exception Handler Reference](/api-reference/exceptions)
- [Request ID Logging](/cookbook/fastapi-request-id-logging)
```

---

## Tasks

- [ ] Create `docs/cookbook/exception-logging-request-context.md`
- [ ] Write context loss problem section
- [ ] Document automatic preservation
- [ ] Add custom handler pattern
- [ ] List structured error fields
- [ ] Test code examples
- [ ] Add cross-links to 12.1

---

## Tests

- Exceptions include request_id
- Structured fields present
- Custom handler integration works

---

## Definition of Done

### Content Complete

- [x] All sections written
- [x] Code examples tested
- [x] Error format verified

### SEO Optimized

- [x] Keywords in H1 and first paragraph
- [x] Under 1000 words

### Integrated

- [x] Added to cookbook index
- [x] Cross-linked with 12.1

---

## Risks / Rollback

### Risks

1. **Risk:** Exception handling not integrated
   - **Mitigation:** Verify fapilog middleware behavior

### Rollback Plan

Revert commit.

---

## Related Stories

- **Depends on:** 12.1 FastAPI request_id logging (introduces request_id concept)

---

## Code Review

**Date:** 2026-01-21
**Reviewer:** Claude
**Verdict:** OK to PR

### Summary

Reviewed cookbook page for exception logging with request context, documenting automatic context preservation and custom handler patterns.

### AC Verification

| Criterion | Evidence |
|-----------|----------|
| AC1: Page exists with correct title | `exception-logging-request-context.md:1` - H1 matches |
| AC2: Problem explained | `exception-logging-request-context.md:5-33` - Default behavior, stack trace, missing fields |
| AC3: Automatic context shown | `exception-logging-request-context.md:37-65` - setup_logging + JSON output |
| AC4: Custom handler pattern | `exception-logging-request-context.md:69-97` - get_request_logger example |
| AC5: Structured fields documented | `exception-logging-request-context.md:101-156` - Table + exc_info example |

### Quality Gates

- [x] Docs build passed
- [x] All links valid
- [x] Code examples verified against actual API
- [x] Word count under 1000 (501 words)

---

## Change Log

| Date | Change | Author |
|------|--------|--------|
| 2026-01-21 | Initial draft | Claude |
| 2026-01-21 | Implementation complete | Claude |
| 2026-01-21 | Code review passed | Claude |
