Skip to content

fix: log SSE payload parse failures instead of silently swallowing them - #1380

Open
omoh5 wants to merge 6 commits into
LabsCrypt:mainfrom
omoh5:fix/1210-log-sse-parse-failures
Open

omoh5 wants to merge 6 commits into
LabsCrypt:mainfrom
omoh5:fix/1210-log-sse-parse-failures

Conversation

@omoh5

@omoh5 omoh5 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Restores observability into a currently invisible failure mode by logging malformed SSE payloads instead of silently discarding them.

Problem

useStreamEvents.ts:96-106 — the handleEvent callback swallows any JSON.parse failure with an empty catch block and no logging:

} catch {
  // Silently ignore malformed event messages
}

This means a corrupted or unexpected SSE frame vanishes without a trace. In a financial application where real-time stream events drive UI state (claimable amounts, status badges, action buttons), silently dropping events can lead to confusing user-facing behavior with zero diagnostic trail.

Solution

  1. Import logger from @/lib/logger — consistent with the codebase convention used in useTokenPrice.ts and useIncomingStreams.ts.

  2. Log the parse failure with structured context in the catch block:

    • type — which SSE event type failed to parse
    • raw — the raw payload string for debugging
    • error — the caught parse error
  3. Added emitRaw() to MockEventSource — test helper that fires a named event with a raw (non-JSON) string payload, enabling malformed-payload testing.

  4. New test: "logs a parse error when SSE payload is malformed" — verifies that:

    • console.error is called (logger.error always surfaces, even in production)
    • The log message contains "SSE payload parse failure"
    • The raw malformed payload appears in the logged arguments
    • The malformed event does NOT appear in the events array

Files Changed

File Change
frontend/src/hooks/useStreamEvents.ts Import logger, replace empty catch with structured error logging
frontend/src/__tests__/useStreamEvents.test.tsx Add emitRaw() to MockEventSource, add malformed-payload test

Test Results

All 15 tests pass (14 existing + 1 new):

✓ src/__tests__/useStreamEvents.test.tsx (15 tests) 99ms

Closes #1210

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

Edukpe David and others added 6 commits August 30, 2026 15:05
Replace npm install with npm ci in backend/Dockerfile (both builder and
runner stages), render.yaml, and vercel.json to ensure deterministic,
lockfile-pinned dependency installs in production builds. This eliminates
the risk of dependency drift between CI-tested and deployed versions.

Closes LabsCrypt#1256

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
The setInterval(updateClaimable, 1000) in stream-details-content.tsx
was running every second regardless of whether the tab was visible,
wasting CPU/battery on backgrounded tabs. This mirrors the approach
already used by the useStreamingAmount hook (requestAnimationFrame +
document.hidden guard) but keeps the bigint arithmetic intact.

- Extract computeClaimable() so the value can be recalculated on demand
- Guard the interval callback with document.hidden check
- Add visibilitychange listener to resync immediately when tab returns
  to foreground (matching useStreamingAmount's resync behavior)
- Add test verifying no state updates occur while document.hidden is true

Closes LabsCrypt#1242

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
The catch block in useStreamEvents.handleEvent was silently ignoring
JSON.parse failures with an empty catch and no logging. This made it
impossible to diagnose malformed SSE frames in production. Now logs
the error, event type, and raw payload via logger.error for debugging.

- Import logger from @/lib/logger (consistent with codebase convention)
- Log parse failures with type, raw payload, and error details
- Add MockEventSource.emitRaw() helper for testing non-JSON payloads
- Add test verifying a malformed SSE frame produces a logged error

Closes LabsCrypt#1210

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
The backend Dockerfile uses npm ci (from PR LabsCrypt#1256) which requires a
package-lock.json. Since this is an npm workspaces monorepo, the
lockfile lived only at the root and wasn't available in the backend/
build context. Generated a standalone backend/package-lock.json so
npm ci can resolve exact dependency versions in the Docker build.

Also added a root .dockerignore for future-proofing.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Audit] SSE payload parse failures vanish silently

1 participant