Session Memory#

IMPORTANT: Keep this file actively updated with conversation summaries, decisions, and progress. Jonathan values having records of our discussions and the evolution of ideas.

Style Guide Reference#

See @docs/style-guide.org for coding patterns, conventions, and architectural guidance.

Recent Work - Error Handling Refactor (COMPLETED ✅)#

Summary#

Successfully refactored from multiple AbortControllers to single connection-level controller with clean error hierarchy and proper timeout handling.

Key Achievements#

  1. Clean Error Hierarchy - HTTP status code-based system with proper differentiation
  2. Single AbortController Architecture - Connection-level controller passes signals down
  3. Robust Timeout Handling - Custom timeoutSignal() with proper cleanup
  4. Signal Composition - Custom combineSignals() preserves abort reasons

Working Error Scenarios#

  • ✅ 3-second timeout → 408 Request Timeout: operation timed out
  • ✅ Socket disconnect → 499 Client Closed Request: operation was aborted
  • ✅ Invalid JSON → 400 Bad Request: validation failed
  • ✅ No spurious errors when operations complete before socket close

Files Modified#

  • src/common/errors.ts - HTTP error hierarchy with status codes
  • src/common/aborts.ts - timeoutSignal() and combineSignals() utilities
  • src/common/socket.ts - Signal-based takeSocket() with reason preservation
  • src/server/socket/handler.ts - Single controller pattern with proper error handling

Key Technical Insights#

  • AbortSignal.timeout() incorrectly throws AbortError instead of TimeoutError in Deno/browsers
  • AbortSignal.any() doesn't preserve individual signal reasons - need custom combineSignals()
  • takeSocket() must reject with signal.reason (not create new error) to preserve error types
  • Timeout cleanup critical when using AbortSignal.any() to prevent lingering timers

Current State#

Project has clean, unified signal-passing architecture with proper error differentiation and timeout handling. Ready for next features.