#23672: fix(resilience): guard JSON.parse of external process output with try-catch
size: S
Cluster:
Gateway Error Handling Improvements
## Summary
- Problem: `JSON.parse` calls parsing external process stdout (tailscale CLI) and disk-persisted queue entries lack try-catch protection, causing unhandled crashes on malformed input
- Why it matters: External process output can be truncated, contain non-JSON preamble text, or be corrupted on disk — all of which cause `SyntaxError` that crashes the gateway
- What changed: Added try-catch guards around `JSON.parse` in `parseTailscaleStatusIPv4s()` (bonjour-discovery.ts) and `failDelivery()` (delivery-queue.ts), returning safe fallback values on parse failure
- What did NOT change: Happy-path behavior is identical; only error recovery is added
## Change Type
- [x] Bug fix
## Scope
- [x] Gateway / orchestration
## Security Impact
- New permissions/capabilities? No
- Secrets/tokens handling changed? No
- New/changed network calls? No
- Command/tool execution surface changed? No
- Data access scope changed? No
## Compatibility / Migration
- Backward compatible? Yes
- Config/env changes? No
- Migration needed? No
## Risks and Mitigations
- Risk: Silent failure on corrupted data could mask underlying issues
- Mitigation: These are recovery paths where the alternative is a process crash; the calling code already handles empty/null returns gracefully
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added defensive `JSON.parse` guards for external process output in two critical paths: Tailscale CLI output parsing (`parseTailscaleStatusIPv4s` in bonjour-discovery.ts:124-130) and disk-persisted delivery queue entries (`failDelivery` in delivery-queue.ts:128-136). Both return safe fallback values (empty array/early return) on parse failure instead of crashing.
- **bonjour-discovery.ts**: `parseTailscaleStatusIPv4s()` now catches malformed/truncated JSON from `tailscale status --json` and returns empty array, preventing gateway crashes during Tailnet discovery fallback
- **delivery-queue.ts**: `failDelivery()` catches corrupted queue JSON and exits silently, preventing crashes during delivery retry attempts
- Test coverage is comprehensive, verifying both truncated JSON and missing files are handled gracefully
- Existing `loadPendingDeliveries()` already had similar protection (line 176), so this brings `failDelivery()` to parity
<h3>Confidence Score: 5/5</h3>
- Safe to merge with no concerns - defensive error handling added to prevent crashes from malformed external data
- Changes are minimal, focused, and follow established error-handling patterns in the codebase (see `loadPendingDeliveries` at line 176 for similar try-catch with graceful skip). Test coverage is comprehensive and verifies the exact failure scenarios. Both changes preserve happy-path behavior while adding critical crash prevention for external/disk data parsing.
- No files require special attention
<sub>Last reviewed commit: 1bc2470</sub>
<!-- greptile_other_comments_section -->
<sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#22993: fix(delivery): guard JSON.parse in failDelivery to prevent silent i...
by adhitShet · 2026-02-21
82.4%
#4653: fix(gateway): improve crash resilience for mDNS and network errors
by AyedAlmudarra · 2026-01-30
77.2%
#3699: fix(gateway): add error handling for tailscaleCleanup in shutdown
by Episkey-G · 2026-01-29
77.2%
#11101: fix: handle AbortError and WebSocket 1006 in unhandled rejection ha...
by Nipurn123 · 2026-02-07
76.0%
#23669: refactor(logging): migrate node-host and tailscale console calls to...
by kevinWangSheng · 2026-02-22
75.9%
#13960: fix(ui): preserve structured config validation error details
by constansino · 2026-02-11
75.8%
#22385: fix: improve delivery recovery logging with entry age and deferral ...
by derrickburns · 2026-02-21
75.6%
#10034: Don't crash gateway on transient unhandled fetch failures
by gigq · 2026-02-06
75.5%
#5823: fix(config): exit cleanly on invalid config instead of high CPU loop
by gavinbmoore · 2026-02-01
75.0%
#14564: fix(gateway): crashes on startup when tailscale meets non-loopback ...
by yinghaosang · 2026-02-12
75.0%