ðŸ›Ąïļ ERROR_HANDLING.md - Error Handling & Resilience Strategy (āļāļĨāļĒāļļāļ—āļ˜āđŒāļāļēāļĢāļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļœāļīāļ”āļžāļĨāļēāļ”āđāļĨāļ°āļ„āļ§āļēāļĄāļĒāļ·āļ”āļŦāļĒāļļāđˆāļ™āļĢāļ°āļšāļš)

This document details SplitDee’s resilience patterns, expected system failure modes, recovery paths, and exception handling protocols.
āđ€āļ­āļāļŠāļēāļĢāļ‰āļšāļąāļšāļ™āļĩāđ‰āđāļŠāļ”āļ‡āđāļœāļ™āļœāļąāļ‡āļĢāļ°āļšāļšāļ„āļ§āļēāļĄāļ—āļ™āļ—āļēāļ™āļ‚āļ­āļ‡ SplitDee, āļ›āļĢāļ°āđ€āļ āļ—āļ‚āđ‰āļ­āļœāļīāļ”āļžāļĨāļēāļ”āļ—āļĩāđˆāļ­āļēāļˆāđ€āļāļīāļ”āļ‚āļķāđ‰āļ™ āđāļ™āļ§āļ—āļēāļ‡āļāļđāđ‰āļ„āļ·āļ™āļĢāļ°āļšāļš āđāļĨāļ°āļĢāļ°āđ€āļšāļĩāļĒāļšāļ›āļāļīāļšāļąāļ•āļīāđƒāļ™āļāļēāļĢāđāļˆāđ‰āļ‡āļ‚āđ‰āļ­āļĒāļāđ€āļ§āđ‰āļ™āļ—āļēāļ‡āđ€āļ—āļ„āļ™āļīāļ„


ðŸ‡đ🇭 āļ āļēāļĐāļēāđ„āļ—āļĒ (āļŠāļģāļŦāļĢāļąāļšāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™)

1. āļĢāļēāļĒāļāļēāļĢāļ‚āđ‰āļ­āļœāļīāļ”āļžāļĨāļēāļ”āļ—āļĩāđˆāļ„āļēāļ”āļāļēāļĢāļ“āđŒāđāļĨāļ°āđāļœāļ™āļāļēāļĢāļāļđāđ‰āļ„āļ·āļ™ (Expected Failures & Recovery)

  • āļĢāļ°āļšāļšāđāļŠāļāļ™āđ€āļŠāđ‡āļāļĒāļ­āļ”āļŠāļĨāļīāļ›āļ˜āļ™āļēāļ„āļēāļĢāļ āļēāļĒāļ™āļ­āļāļĨāđˆāļĄ/āļŦāļĄāļ”āđ€āļ§āļĨāļē:
    • āļ›āļąāļāļŦāļē: āļĢāļ°āļšāļšāļ āļēāļĒāļ™āļ­āļ (āđ€āļŠāđˆāļ™ SlipOK) āļ•āļ­āļšāļāļĨāļąāļšāļŦāļĄāļ”āđ€āļ§āļĨāļē 504 āļŦāļĢāļ·āļ­āļ‚āļēāļ”āļāļēāļĢāđ€āļŠāļ·āđˆāļ­āļĄāļ•āđˆāļ­
    • āļāļēāļĢāļāļđāđ‰āļ„āļ·āļ™: āļŦāļĨāļąāļ‡āļšāđ‰āļēāļ™āđāļ­āļ›āļˆāļ°āđ„āļĄāđˆāđāļ„āļĢāļŠāļĨāđ‰āļĄāđ€āļŦāļĨāļ§ āļ—āļģāļāļēāļĢāļšāļąāļ™āļ—āļķāļāļ›āļĢāļ°āļ§āļąāļ•āļīāđ€āļ›āđ‡āļ™ â€˜āļĢāļ­āļ•āļĢāļ§āļˆāļŠāļ­āļšāļ”āđ‰āļ§āļĒāļ•āļēāđ€āļ›āļĨāđˆāļē’ (pending_manual) āļ„āđ‰āļēāļ‡āļŠāļ–āļēāļ™āļ°āļŦāļ™āļĩāđ‰āļĨāļđāļāļŦāļ™āļĩāđ‰āđ„āļ§āđ‰āđ€āļ›āđ‡āļ™āļĢāļ°āļŦāļ§āđˆāļēāļ‡āļ•āļĢāļ§āļˆāļŠāđ„āļĨāļ”āđŒ (processing) āđāļˆāđ‰āļ‡āļĨāļđāļāļŦāļ™āļĩāđ‰āđƒāļŦāđ‰āļ§āļēāļ‡āđƒāļˆāļĒāļ­āļ”āđ„āļ”āđ‰āļĢāļąāļšāļŠāđāļāļ™āđāļĨāđ‰āļ§ āđāļĨāļ°āļĒāļīāļ‡āļ āļēāļĢāļāļīāļˆāļ•āļĢāļ§āļˆāđāļ­āļ› Statement āļŠāđˆāļ‡āļ–āļķāļ‡āđ€āļˆāđ‰āļēāļŦāļ™āļĩāđ‰āđ€āļžāļ·āđˆāļ­āļāļ”āļĒāļ·āļ™āļĒāļąāļ™āļ”āđ‰āļ§āļĒāļĄāļ·āļ­āđ€āļ›āļĨāđˆāļē
  • āļāļēāļĢāļ™āļģāļŠāļĨāļīāļ›āđ€āļāđˆāļēāļĄāļēāđāļŠāļāļ™āđ‚āļ­āļ™āļ‹āđ‰āļģāļŠāļ­āļ‡āļĢāļ­āļš (Duplicate Slip / Double-Spending):
    • āļ›āļąāļāļŦāļē: āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āļŠāđˆāļ‡āļŠāļĨāļīāļ›āđ€āļ”āļīāļĄāļ—āļĩāđˆāļ•āļĢāļ§āļˆāļ›āļĢāļ°āļ§āļąāļ•āļīāļœāđˆāļēāļ™āđ„āļ›āđāļĨāđ‰āļ§ āļŦāļ§āļąāļ‡āđ€āļ„āļĨāļĩāļĒāļĢāđŒāļšāļīāļĨāļŦāļēāļĢāđ€āļ‡āļīāļ™āđƒāļšāđƒāļŦāļĄāđˆ
    • āļāļēāļĢāļāļđāđ‰āļ„āļ·āļ™: āļ•āļĢāļ§āļˆāļĢāļŦāļąāļŠāļ˜āļļāļĢāļāļĢāļĢāļĄāļāļēāļĢāđ‚āļ­āļ™āļ‚āļ­āļ‡āļ˜āļ™āļēāļ„āļēāļĢāļŠāļ™āļāļąāļšāļĢāļ°āļšāļšāļ”āļąāļŠāļ™āļĩāļ„āļĩāļĒāđŒāļˆāļģāļāļąāļ”āļŦāđ‰āļēāļĄāļ‹āđ‰āļģ (slip_trans_id) āđ‚āļžāļŠāļ•āđŒāđ€āļāļĢāļˆāļ°āđ„āļĄāđˆāļĒāļ­āļĄāđƒāļŦāđ‰āđ€āļ‚āļĩāļĒāļ™āđāļ–āļ§āļ›āļĢāļ°āļ§āļąāļ•āļīāļ‹āđ‰āļģ āđāļĨāļ°āļĒāļīāļ‡āđ€āļ•āļ·āļ­āļ™āļœāļđāđ‰āļŠāđˆāļ‡āļ„āļ·āļ™āļĒāļ­āļ”āļ§āđˆāļē ‘āļŠāļĨāļīāļ›āļ™āļĩāđ‰āļ–āļđāļāđƒāļŠāđ‰āļĒāļ·āļ™āļĒāļąāļ™āļĒāļ­āļ”āđ€āļ‡āļīāļ™āđ„āļ›āđāļĨāđ‰āļ§â€™ āđāļĨāļ°āļ”āļĩāļ”āļŠāđ€āļ•āļ•āļąāļŠāļāļĨāļąāļšāđ€āļ›āđ‡āļ™āļĒāļąāļ‡āđ„āļĄāđˆāļˆāđˆāļēāļĒāļ—āļąāļ™āļ—āļĩ
  • āļŠāđāļāļ™āļĢāļđāļ›āļ„āļīāļ§āļ­āļēāļĢāđŒāļžāļĢāđ‰āļ­āļĄāđ€āļžāļĒāđŒāļ—āļĩāđˆāļ­āļ­āļāđ„āļ§āđ‰āļ™āļēāļ™āļˆāļ™āļĨāđ‰āļēāļŦāļĨāļąāļ‡āļŦāļĄāļ”āļ­āļēāļĒāļļ:
    • āļ›āļąāļāļŦāļē: āļŠāļĄāļēāļŠāļīāļāļĢāļ·āđ‰āļ­āļ„āļīāļ§āļ­āļēāļĢāđŒāļžāļĢāđ‰āļ­āļĄāđ€āļžāļĒāđŒāđƒāļšāđ€āļāđˆāļēāļĄāļēāļāđˆāļ­āļ™āļŦāļ™āđ‰āļēāļ™āļĩāđ‰ āļ‹āļķāđˆāļ‡āļšāļīāļĨāļĄāļĩāļāļēāļĢāđāļāđ‰āđ„āļ‚āļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļŦāļ™āļĩāđ‰āļŠāļīāļ™āļŦāļĢāļ·āļ­āļ–āļđāļāļœāļđāđ‰āļŠāļĢāđ‰āļēāļ‡āļĨāļšāđ„āļ›āđāļĨāđ‰āļ§
    • āļāļēāļĢāļāļđāđ‰āļ„āļ·āļ™: āđāļĄāđ‰āđ€āļ‡āļīāļ™āļˆāļ°āđ€āļ‚āđ‰āļēāļ˜āļ™āļēāļ„āļēāļĢ āđāļ•āđˆāđ€āļ§āļĨāļēāļ­āļąāļ›āđ‚āļŦāļĨāļ”āļĢāļ°āļšāļšāļˆāļ°āļŠāđāļāļ™āļ§āļąāļ™āđāļĨāļ°āđ€āļ§āļĨāļēāļˆāļĢāļīāļ‡āļ‚āļ­āļ‡āļ˜āļ™āļēāļ„āļēāļĢāļĄāļēāđ€āļŠāđ‡āļāđ€āļ—āļĩāļĒāļšāļāļąāļšāđ€āļ§āļĨāļēāļ›āļĢāļąāļšāļ›āļĢāļļāļ‡āļŠāđ€āļ›āļāļšāļīāļĨāļŦāļĨāļąāļ‡āļšāđ‰āļēāļ™ āļŦāļēāļāļ•āļĢāļ§āļˆāļžāļšāļ§āđˆāļēāđ‚āļ­āļ™āļāđˆāļ­āļ™āļ­āļąāļ›āđ€āļ”āļ•āđāļāđ‰āļĒāļ­āļ”āļŦāļ™āļĩāđ‰āļˆāļĢāļīāļ‡ āļˆāļ°āļ—āļģāļāļēāļĢāļŠāđˆāļ‡āļ›āļāļīāđ€āļŠāļ˜āļŠāļĨāļīāļ›āļ™āļąāđ‰āļ™āđāļĨāļ°āļ•āļąāđ‰āļ‡āļ„āđˆāļēāđ€āļ›āđ‡āļ™ āļĒāļ­āļ”āđ„āļĄāđˆāļ•āļĢāļ‡ āļŦāļĢāļ·āļ­ āļŠāļĨāļīāļ›āļŦāļĄāļ”āļ­āļēāļĒāļļāļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™

2. āļāļēāļĢāļ„āļ§āļšāļ„āļļāļĄāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒāļ›āđ‰āļ­āļ‡āļāļąāļ™āļĢāļēāļĒāļāļēāļĢāļĢāļąāļ™āļžāļĢāđ‰āļ­āļĄāļāļąāļ™ (Concurrency & Race Condition)

  • āļĨāļđāļāļŦāļ™āļĩāđ‰āļŠāđˆāļ‡āļŠāļĨāļīāļ›āļĢāļąāļ§āļ›āļļāđˆāļĄāļžāļĢāđ‰āļ­āļĄāđ† āļāļąāļ™:
    • āļāļēāļĢāļāļđāđ‰āļ„āļ·āļ™: āļĢāļ°āļ”āļąāļšāđ€āļšāļŠāļĄāļĩāļ•āļēāļĢāļēāļ‡āļ„āļĩāļĒāđŒāļ„āļļāļĄāļŠāļąāļ”āļŠāđˆāļ§āļ™āļŠāđˆāļ§āļ™āļŦāļ™āļĩāđ‰āđ€āļ”āļĩāđˆāļĒāļ§ āđāļĨāļ°āļĢāļ°āļ”āļąāļšāđ‚āļ„āđ‰āļ”āļŦāļĨāļąāļ‡āļšāđ‰āļēāļ™āļĄāļĩāļ•āļąāļ§āļĄāļąāļ”āļĨāđ‡āļ­āļāļŠāļąāđˆāļ§āļ„āļĢāļēāļ§āļœāđˆāļēāļ™ Redis (lock_key) āļ•āļąāļ§āļĨāđ‡āļ­āļāļˆāļ°āļ„āļĨāļēāļĒāļ­āļ­āļāļ•āđˆāļ­āđ€āļĄāļ·āđˆāļ­āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļāļēāļĢāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāđ‚āļ­āļ™āđ€āļŠāļĢāđ‡āļˆāļŠāļīāđ‰āļ™ āđ€āļžāļ·āđˆāļ­āđ„āļĄāđˆāđƒāļŦāđ‰āđāļ„āļĢāļŠāļ‚āđ‰āļ­āļĄāļđāļĨāļāļēāļĢāđ‚āļ­āļ™āļŠāļ™āļāļąāļ™
  • āļāļēāļĢāđ€āļ‚āļĩāļĒāļ™āļ•āļēāļĢāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļĨāđ‰āļĄāđ€āļŦāļĨāļ§āļāļĨāļēāļ‡āļ„āļąāļ™:
    • āļāļēāļĢāļāļđāđ‰āļ„āļ·āļ™: āļŦāđˆāļ­āļŦāļļāđ‰āļĄāļ„āļģāļŠāļąāđˆāļ‡āļāļēāļĢāļŦāļēāļĢāļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāđ„āļ§āđ‰āđƒāļ•āđ‰ Database Transaction āļāđ‰āļ­āļ™āđ€āļ”āļĩāļĒāļ§āļāļąāļ™ āļŦāļēāļāđ€āļāļīāļ”āļ„āļ§āļēāļĄāļœāļīāļ”āļžāļĨāļēāļ”āđƒāļ”āđ† āļāļĨāļēāļ‡āļ„āļąāļ™ (āđ€āļŠāđˆāļ™ āļŦāļąāļ XP āļ•āļāļŦāļĨāđˆāļ™) āļĢāļ°āļšāļšāļˆāļ°āļāļ”āļĒāļāđ€āļĨāļīāļāļāļēāļĢāļšāļąāļ™āļ—āļķāļāļĒāđ‰āļ­āļ™āļŦāļĨāļąāļ‡ (Rollback) 100% āđ€āļžāļ·āđˆāļ­āļĢāļąāļāļĐāļēāļĢāļ°āļ”āļąāļšāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļēāļāļĨāđƒāļŦāđ‰āļŠāļĄāļšāļđāļĢāļ“āđŒ

3. āļžāļĪāļ•āļīāļāļĢāļĢāļĄāđ€āļĄāļ·āđˆāļ­āļĄāļ·āļ­āļ–āļ·āļ­āđ„āļĄāđˆāļĄāļĩāđ€āļ™āđ‡āļ• (Offline Mode)

  • āļāļēāļĢāļ­āđˆāļēāļ™āļ›āļĢāļ°āļ§āļąāļ•āļī: āđ‚āļ—āļĢāļĻāļąāļžāļ—āđŒāļˆāļ°āļ”āļķāļ‡āļ›āļĢāļ°āļ§āļąāļ•āļīāļāļĨāļļāđˆāļĄ āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļšāļīāļĨ āđāļĨāļ°āļŠāđ€āļ•āļ•āļąāļŠāđ‚āļĄāļˆāļīāļˆāļēāļāđāļ„āļŠāđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļ āļēāļĒāđƒāļ™āđƒāļŦāđ‰āļœāļđāđ‰āđƒāļŠāđ‰āļ”āļđāđ„āļ”āđ‰āđāļĄāđ‰āđ„āļĄāđˆāļĄāļĩāđ€āļ™āđ‡āļ•
  • āļāļēāļĢāļ—āļģāļĢāļēāļĒāļāļēāļĢāđƒāļŦāļĄāđˆ: āļĢāļ°āļšāļšāļšāļĨāđ‡āļ­āļāļ›āļļāđˆāļĄāđƒāļŠāđ‰āļ‡āļēāļ™āļŠāļĢāđ‰āļēāļ‡āļāļĨāļļāđˆāļĄ āļŦāļēāļĢāļšāļīāļĨ āđāļĨāļ°āđāļŠāļāļ™āļ•āļĢāļ§āļˆāļŠāļĨāļīāļ›āļ—āļąāļ™āļ—āļĩāļŦāļēāļāļ­āļ­āļŸāđ„āļĨāļ™āđŒ āļžāļĢāđ‰āļ­āļĄāļ‚āļķāđ‰āļ™āđ€āļ•āļ·āļ­āļ™ â€˜āļāļĢāļļāļ“āļēāđ€āļŠāļ·āđˆāļ­āļĄāļ­āļīāļ™āđ€āļ•āļ­āļĢāđŒāđ€āļ™āđ‡āļ•āđ€āļžāļ·āđˆāļ­āļ—āļģāļĢāļēāļĒāļāļēāļĢ’ āđ€āļžāļ·āđˆāļ­āļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒ

🇎🇧 English (For AI Agents)

1. Expected Failures & Recovery Paths

  • Slip Verification API Timeout / Outage
    • Failure Scenario: The third-party bank transaction check API (e.g. SlipOK) returns a 504 Gateway Timeout or is completely unreachable.
    • Immediate Recovery: The API catches the exception, updates the payment record to pending_manual, locks the share status as processing, informs the debtor, and queues a manual approval card in the creditor’s feed.
  • Duplicate Slip / Double-Spending Attempt
    • Failure Scenario: A user uploads a slip with a bank transaction ID that has already been verified in the system.
    • Handling Protocol: Database level unique constraints on slip_trans_id reject duplicate rows, HTTP 400 with code SLIP_ALREADY_USED is returned to the client, and the share is reset to unpaid.
  • Expired PromptPay QR Code
    • Failure Scenario: A debtor scans and pays using a PromptPay QR code containing outdated bill split values.
    • Handling Protocol: Compare the bank transaction statement timestamp with the bill modification timestamp. If the payment occurred before the last bill update, reject the slip with code SLIP_AMOUNT_MISMATCH or PAYMENT_EXPIRED.

2. Concurrency & Race Condition Protections

  • Concurrent Slip Uploads
    • Resolution: Composite database unique constraints on (bill_id, user_id) and slip_trans_id. Acquire a Redis distributed lock lock:share:{share_id} during verification, releasing it only on success or rollback.
  • Relational Transaction Rollback
    • Resolution: Wrap use case actions inside atomic database transactions. Execute rollbacks on any sub-action failure to preserve data integrity.

3. Offline Mode Behavior

  • Read Operations: Cached local storage (SQLite/Hive) allows users to view group details, bill history, and Mochi’s status offline.
  • Write Operations: Operations like creating groups, publishing bills, or verifying slips are blocked. Show error “Internet connection required to perform this action.”