Files
triqura-ecd/docs/swift/test-plan-e5-s2-error-handling.md
colinislit 33c6698870 feat(swift): Epic 5 Progress - Error Handling & Keyboard Shortcuts (E5.S2-S3)
Epic 5 deels compleet: Error handling en keyboard shortcuts geïmplementeerd.
Voortgang: 62 SP / 72 SP (86%) - Nog 1 story voor MVP compleet!

E5.S2 - Error Handling (2 SP)
- Gecentraliseerde error handler utility (lib/swift/error-handler.ts)
- isOffline(), isNetworkError(), getErrorInfo() functies
- safeFetch() wrapper met 30s timeout en retry logic
- retryFetch() met exponential backoff (max 3 retries)
- User-friendly Nederlandse error messages voor alle HTTP status codes
- OfflineBanner component met online/offline detection
- Alle blocks en CommandInput gebruiken nieuwe error handler
- Context bar margin adjustment voor offline banner
- parseErrorResponse() voor HTML error detection

E5.S3 - Keyboard Shortcuts (2 SP)
- ⌘Enter / Ctrl+Enter quick submit in CommandInput
- ⌘Enter / Ctrl+Enter quick save in DagnotatieBlock
- Visual hints (⌘↵) op submit button in DagnotatieBlock
- Geverifieerd: ⌘K focus, Escape close, 1-3 FallbackPicker
- Cross-platform support (macOS + Windows/Linux)
- preventDefault() voor browser conflict preventie

Components Updated:
- DagnotatieBlock: safeFetch, getErrorInfo, retryFetch, ⌘Enter save
- OverdrachtBlock: safeFetch, retryFetch voor AI generation
- ZoekenBlock: safeFetch, getErrorInfo voor patient search
- CommandInput: safeFetch, getErrorInfo, ⌘Enter submit
- CommandCenter: OfflineBanner integration
- ContextBar: useOffline hook voor margin adjustment

Nieuwe Files:
- lib/swift/error-handler.ts (301 regels) - Error handling utilities
- components/swift/command-center/offline-banner.tsx (72 regels)
- docs/swift/keyboard-shortcuts-reference.md (200+ regels)
- docs/swift/test-plan-e5-s2-error-handling.md (350+ regels)
- docs/swift/test-plan-e5-s3-keyboard-shortcuts.md (350+ regels)
- docs/swift/PROJECT-STATUS-2024-12-27.md (500+ regels) - Status report

Documentatie:
- Bouwplan bijgewerkt naar v2.5
- Epic completion details toegevoegd met progress bars
- Manual test checklist bijgewerkt (17/20 scenarios)
- Risico's sectie bijgewerkt (alle major risks gemitigeerd)
- Sprint planning status: E5 75% compleet (6/8 SP)

Technische verbeteringen:
- Offline detection met visual feedback
- Network error retry met exponential backoff
- HTTP 401/404/500/503 error messages in Nederlands
- Timeout protection (30s) op alle API calls
- Keyboard shortcuts met visual hints
- Cross-platform shortcut support

Testing:
- Error handling test plan met 8 categorieën
- Keyboard shortcuts test plan met 6 categorieën
- 40+ test scenarios gedocumenteerd
- Quick smoke test checklists

Voortgang: 62 SP / 72 SP (86%) - E5.S2 en E5.S3 compleet

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 09:27:32 +01:00

7.6 KiB

Test Plan E5.S2 - Error Handling

Datum: 27-12-2024 Status: Ready for Testing Story: E5.S2 - Error handling (2 SP)


Implementatie Overzicht

Nieuwe bestanden:

  1. lib/swift/error-handler.ts - Error handling utility met:

    • isOffline() - Detect browser offline status
    • isNetworkError() - Network error detection
    • isTimeoutError() - Timeout detection
    • parseErrorResponse() - Parse HTTP error responses
    • getErrorInfo() - Generate user-friendly error messages
    • safeFetch() - Fetch wrapper met timeout (30s)
    • retryFetch() - Retry logic met exponential backoff
  2. components/swift/command-center/offline-banner.tsx - Offline banner component

    • Toont amber banner bij !navigator.onLine
    • useOffline() hook voor offline detection

Geüpdatete bestanden:

  1. components/swift/command-center/command-center.tsx - OfflineBanner geïntegreerd
  2. components/swift/command-center/command-input.tsx - Error handling met safeFetch/getErrorInfo
  3. components/swift/command-center/context-bar.tsx - useOffline hook voor margin adjustment
  4. components/swift/blocks/dagnotitie-block.tsx - safeFetch, getErrorInfo, retryFetch
  5. components/swift/blocks/zoeken-block.tsx - safeFetch, getErrorInfo
  6. components/swift/blocks/overdracht-block.tsx - safeFetch, getErrorInfo, retryFetch

🧪 Test Scenarios

1. Offline Detection

Test 1.1: Browser Offline

  • Open DevTools → Network tab → Throttling → Offline
  • Amber banner verschijnt bovenaan: "Geen internetverbinding"
  • Context bar heeft marginTop: 40px (geen overlap)
  • Try een actie (dagnotitie opslaan, patient zoeken)
  • Toast shows: "Geen internetverbinding - Controleer je internetverbinding en probeer het opnieuw."

Test 1.2: Reconnect

  • Zet network weer op "Online"
  • Banner verdwijnt automatisch
  • Context bar margin reset
  • Acties werken weer normaal

2. Network Errors

Test 2.1: API Endpoint Down

  • Stop de dev server (kill process)
  • Probeer dagnotitie opslaan
  • Toast shows: "Verbinding verbroken - Kon geen verbinding maken met de server."
  • Retry button beschikbaar (voor retryable errors)

Test 2.2: Timeout (30s)

  • Simuleer slow API (add await new Promise(r => setTimeout(r, 35000)) in API route)
  • Probeer actie
  • Na 30 seconden: Toast shows "Verbinding timeout"

3. HTTP Status Codes

Test 3.1: 401 Unauthorized

  • Simuleer 401 in API route: return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  • Toast shows: "Niet geautoriseerd - Je sessie is verlopen. Log opnieuw in."
  • retryable: false (geen retry button)

Test 3.2: 404 Not Found

  • Probeer non-existent patient ID: /api/fhir/Patient/99999999
  • Toast shows: "Niet gevonden - Patiënt data ophalen niet gevonden."

Test 3.3: 400 Bad Request

  • Submit dagnotitie zonder required fields
  • Toast shows: "Ongeldige aanvraag - [validation message]"

Test 3.4: 500 Internal Server Error

  • Simuleer server error in API route: throw new Error('DB error')
  • Toast shows: "Serverfout - Er ging iets mis op de server. Probeer het later opnieuw."
  • retryable: true

Test 3.5: 429 Too Many Requests

  • (Moeilijk te simuleren zonder rate limiter)
  • Toast should show: "Te veel aanvragen - Wacht even en probeer het later opnieuw."

4. Validation Errors

Test 4.1: Empty Fields in DagnotatieBlock

  • Open dagnotitie block
  • Klik "Opslaan" zonder patiënt
  • Toast shows: "Validatiefout - Selecteer een patiënt"
  • Klik "Opslaan" zonder categorie
  • Toast shows: "Validatiefout - Selecteer een categorie"
  • Klik "Opslaan" zonder tekst
  • Toast shows: "Validatiefout - Voer een notitie in"

Test 4.2: Search Query Too Short

  • Type "j" in ZoekenBlock (< 2 characters)
  • Geen API call (debounced + min length check)

5. Intent Classification Errors

Test 5.1: API Error

  • Typ commando in command input
  • Simuleer API error in /api/intent/classify
  • Toast shows error message
  • FallbackPicker opent automatisch met original input
  • Input is niet verloren (preserved in FallbackPicker)

Test 5.2: Low Confidence

  • Typ gibberish: "asdfasdf jkljkl"
  • Confidence < 0.5
  • FallbackPicker opent met original input
  • Can select fallback action (dagnotitie, zoeken, overdracht)

6. Retry Logic

Test 6.1: Retry Success on 2nd Attempt

  • Simuleer intermittent error (fails first, succeeds second)
  • DagnotatieBlock save with retryFetch()
  • Should retry automatically (max 3 attempts)
  • Success toast after retry succeeds

Test 6.2: Retry Exhausted (3 failures)

  • Simuleer consistent error (always fails)
  • After 3 retries: Final error toast shown
  • No infinite retry loop

7. User-Friendly Messages (Dutch)

Test 7.1: All Error Messages in Dutch

  • Check all toast messages are in Dutch
  • Check all error titles are in Dutch
  • No English fallback messages visible to user

Test 7.2: Error Message Quality

  • Messages are actionable ("Controleer je internetverbinding")
  • Not technical jargon ("fetch failed" → "Verbinding verbroken")
  • Clear next steps when applicable

8. Edge Cases

Test 8.1: HTML Error Response (Auth Redirect)

  • Simulate HTML response (login page redirect)
  • parseErrorResponse() detects HTML
  • Toast shows: "Niet geautoriseerd. Log opnieuw in."

Test 8.2: Malformed JSON Response

  • Simulate invalid JSON from API
  • Error handled gracefully (no crash)
  • User-friendly error shown

Test 8.3: Error During Voice Input

  • Start voice recording
  • Trigger error (offline, etc.)
  • Voice recording stops gracefully
  • Error shown to user

Implementation Checklist

  • lib/swift/error-handler.ts created with all utilities
  • components/swift/command-center/offline-banner.tsx created
  • OfflineBanner integrated in CommandCenter
  • CommandInput uses safeFetch + getErrorInfo
  • ContextBar uses useOffline hook (margin adjustment)
  • DagnotatieBlock uses safeFetch + getErrorInfo + retryFetch
  • ZoekenBlock uses safeFetch + getErrorInfo
  • OverdrachtBlock uses safeFetch + getErrorInfo + retryFetch
  • All error messages in Dutch
  • FallbackPicker handles unknown intents gracefully
  • TypeScript compiles without errors

📋 Manual Testing Checklist (Quick Smoke Test)

Voor snelle verificatie:

  1. Offline Mode:

    • DevTools → Offline → Banner appears → Try action → Error toast
  2. Network Error:

    • Stop server → Try action → Error toast with retry
  3. Validation Error:

    • Submit empty dagnotitie → Validation toast
  4. Intent Error:

    • Type gibberish → FallbackPicker opens
  5. Success Path:

    • Online → Submit dagnotitie → Success toast → Block closes

🎯 Acceptatie Criteria E5.S2

  • Network errors tonen user-friendly messages (Dutch)
  • Offline detection met visual indicator (banner)
  • Validation errors zijn duidelijk en actionable
  • Retry functionaliteit werkt voor transient errors
  • HTTP status codes mapped naar begrijpelijke messages
  • FallbackPicker shown on intent classification failure
  • No lost user input on errors (preserved in FallbackPicker)
  • All error scenarios from test-plan-epic3.md covered

🚀 Status

E5.S2 - Error Handling: COMPLETE

All error handling utilities implemented, integrated across all components, and ready for testing.