fix: handle invalid webhook jsonPayload without crashing#3019
fix: handle invalid webhook jsonPayload without crashing#3019badja-dev wants to merge 4 commits into
Conversation
The GET /webhook API route called JSON.parse(Buffer.from(jsonPayload, 'base64')) with no error handling. If jsonPayload was empty or malformed (e.g. after a settings migration), the route threw an unhandled exception and returned HTTP 500. The frontend webhook settings component used `if (!data && !error)` as its only loading guard. When the API returned 500, `data` was undefined and `error` was truthy - the component fell through and crashed on `data.enabled`. Fixes: - Wrap the JSON.parse call in notifications.ts in a try/catch with a safe fallback - Add an explicit error state render in NotificationsWebhook/index.tsx
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughServer GET /webhook now safely decodes/parses ChangesWebhook settings error handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/Settings/Notifications/NotificationsWebhook/index.tsx`:
- Line 212: Replace the hardcoded string "Failed to load webhook settings.
Please check your configuration and try refreshing." with a localized message:
add a messages object via defineMessages (e.g., const messages =
defineMessages({ loadError: { id: 'notifications.webhook.loadError',
defaultMessage: 'Failed to load webhook settings. Please check your
configuration and try refreshing.' } })) and use
intl.formatMessage(messages.loadError) where the string is currently used
(ensure the component has access to the intl prop via injectIntl or useIntl and
reference the component name NotificationsWebhook or the render function that
contains the message).
- Around line 209-214: The component currently returns an error UI when error is
truthy but later dereferences SWR's data (e.g., data.enabled) without guarding
for the loading state; add a loading guard that checks for !data (or data ===
undefined) before accessing fields used as form initial values in this
NotificationsWebhook component (where data and error come from the SWR hook),
and render a loading placeholder (or return null) until data is available to
prevent runtime crashes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 376964b7-5256-4823-b5f3-10418ef9349d
📒 Files selected for processing (2)
server/routes/settings/notifications.tssrc/components/Settings/Notifications/NotificationsWebhook/index.tsx
…ges. purely defensive. try/catc two files touched, no logic changes, purely defensive. The bakcend change wraps one existing `JSON.parse` call in a try-catch so the GET `/webook` route returns and empty string fallback instead of throwing a 500 when the stored payload is malformed. The frontend change adds two missing guard clauses - one to render an error panel when the API call fails, and one to hold the loading spinner until `data` is actually available - preventing a crash on `data.enabled` when `data` is undefined. No new features, no shcema changes, no changes to how payloads are saved or sent
Description
I noticed an error in my Seerr logs where a webhook notification was failing with
"[object Object]" is not valid JSON. When I went to check the webhook settings page to investigate, I was met with an "Oops" crash screen instead.After digging into the network tab I found the settings page API was returning HTTP 500. The GET /webhook route in notifications.ts calls
JSON.parse(Buffer.from(jsonPayload, 'base64'))with no error handling - if the stored payload is empty or malformed (which can happen after a settings migration), it throws an unhandled exception. The frontend only guarded against a loading state withif (!data && !error)and had no handling for the error case, so when the API returned 500,datawas undefined and the component crashed ondata.enabled.Changes:
How Has This Been Tested?
Reproduced on my own Seerr v3.2.0 Docker instance. The settings page crashed consistently before the fix and loaded correctly after. I also ran
pnpm buildlocally and it completed without errors or warnings from the changed files.Screenshots / Logs (if applicable)
Log error that triggered the investigation:
Browser console errors on the Oops screen:
Checklist:
pnpm buildpnpm i18n:extractSummary by CodeRabbit
Bug Fixes
Localization