Skip to content

Bug: Success-path res.json() calls in monitor mutation hooks lack .catch() fallback #319

@bd73-com

Description

@bd73-com

Bug: Success-path res.json() calls in monitor mutation hooks lack .catch() fallback

Severity: low
Location: client/src/hooks/use-monitors.ts:107, client/src/hooks/use-monitors.ts:197, client/src/hooks/use-monitors.ts:241

Background / Context

The mutation hooks useUpdateMonitor, useCheckMonitorSilent, and useUpdateMonitorSilent in client/src/hooks/use-monitors.ts call await res.json() on their success paths (after confirming res.ok is true) without a .catch(() => ({})) fallback. This is the same class of issue as #308 and #310 (which cover error paths), but affects the success path instead. If an intermediary proxy or CDN returns a 200 response with a non-JSON body (e.g., an HTML page from a misconfigured load balancer), the res.json() call throws a SyntaxError. React Query catches the thrown error, so the app does not crash, but the user sees an unhelpful SyntaxError message instead of a meaningful response.

How to Reproduce

  1. Log in to FetchTheChange and navigate to a monitor detail page.
  2. Trigger a condition where a reverse proxy or CDN returns a 200 status with an HTML body instead of JSON for PATCH /api/monitors/:id or POST /api/monitors/:id/check. This can happen when:
    • A transparent caching proxy serves a stale HTML response.
    • A CDN or WAF inserts a challenge page but returns 200 instead of a proper error status.
  3. Edit and save a monitor (triggers useUpdateMonitor), or use the Fix Selector flow (triggers useCheckMonitorSilent and useUpdateMonitorSilent).

Actual Result

The mutation enters React Query's error state with a SyntaxError message like "Unexpected token '<', '<!DOCTYPE '... is not valid JSON". For useUpdateMonitor, the toast shows this unhelpful error. For useCheckMonitorSilent and useUpdateMonitorSilent, there is no onError handler, so the error is silently swallowed by React Query -- the UI gives no feedback at all about the failure.

Expected Result

The success-path res.json() calls should include a .catch() fallback or a pre-check of the Content-Type header, so that non-JSON 200 responses produce a clear, actionable error message (e.g., "Unexpected response format from server") rather than a raw SyntaxError.

Affected hooks

  • useUpdateMonitor() — line 107
  • useCheckMonitorSilent() — line 197
  • useUpdateMonitorSilent() — line 241

Found by

Magicwand Phase 6 (Bug Reporter) on branch claude/fix-github-issues-C9ztu

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglowLow severity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions