invalid uuid check is returning a plain object instead of sending HTTP response#2734
invalid uuid check is returning a plain object instead of sending HTTP response#2734adityamane765 wants to merge 3 commits into
Conversation
📝 WalkthroughWalkthroughControllers in src/api/controllers/config.js now send HTTP 400 JSON for invalid UUID parameters in getConfigPool, and getDistinctID/getConfigPool/getAllPools throw AppError('Couldn't get data', 404) when DB queries return no data; app errorHandler now returns JSON using err.statusCode. ChangesConfig controller error handling
Sequence Diagram(s)sequenceDiagram
participant Client
participant getConfigPool
participant getDistinctID
participant getAllPools
participant Database
participant errorHandler
Client->>getConfigPool: HTTP request (configID)
getConfigPool->>Database: query by configID
Database-->>getConfigPool: null / no data
getConfigPool->>errorHandler: throw AppError('Couldn't get data',404)
Client->>getDistinctID: HTTP request
getDistinctID->>Database: distinct ID query
Database-->>getDistinctID: null
getDistinctID->>errorHandler: throw AppError('Couldn't get data',404)
Client->>getAllPools: HTTP request
getAllPools->>Database: query all pools
Database-->>getAllPools: null
getAllPools->>errorHandler: throw AppError('Couldn't get data',404)
errorHandler->>Client: HTTP response (res.status(err.statusCode||500).json({status: err.status ?? 'error', message: err.message}))
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/api/controllers/config.js (1)
30-32:⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy liftPotential error handling issue - same pattern as the bug fixed on line 44. The code returns
new AppError(...)without throwing it or passing it to Express error middleware. If no error middleware automatically catches AppError instances, these responses will hang.
src/api/controllers/config.js#L30-L32: IngetDistinctID, change tothrow new AppError(...)or send response directly withres.status(404).json(...)src/api/controllers/config.js#L56-L58: IngetConfigPool, change tothrow new AppError(...)or send response directly withres.status(404).json(...)src/api/controllers/config.js#L81-L83: IngetAllPools, change tothrow new AppError(...)or send response directly withres.status(404).json(...)🤖 Prompt for 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. In `@src/api/controllers/config.js` around lines 30 - 32, In src/api/controllers/config.js (lines 30-32, 56-58, 81-83) the handlers getDistinctID, getConfigPool, and getAllPools currently return new AppError(...) which does not propagate; change each site to throw new AppError(...) instead (so the central Express error middleware handles it) — specifically replace the return new AppError(...) in getDistinctID (30-32), getConfigPool (56-58) and getAllPools (81-83) with throw new AppError(...) (alternatively you may send an immediate response with res.status(404).json(...) if you prefer per-handler responses, but keep behavior consistent across these three functions).
🤖 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.
Outside diff comments:
In `@src/api/controllers/config.js`:
- Around line 30-32: In src/api/controllers/config.js (lines 30-32, 56-58,
81-83) the handlers getDistinctID, getConfigPool, and getAllPools currently
return new AppError(...) which does not propagate; change each site to throw new
AppError(...) instead (so the central Express error middleware handles it) —
specifically replace the return new AppError(...) in getDistinctID (30-32),
getConfigPool (56-58) and getAllPools (81-83) with throw new AppError(...)
(alternatively you may send an immediate response with res.status(404).json(...)
if you prefer per-handler responses, but keep behavior consistent across these
three functions).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 26ef6027-93a2-415f-b414-aa411baf3f8f
📒 Files selected for processing (1)
src/api/controllers/config.js
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/api/controllers/config.js`:
- Around line 30-32: The controllers throw AppError but the centralized
errorHandler always returns 500+HTML, so fix the controllers to respond with
proper 404 JSON at the three sites rather than relying on AppError: in
src/api/controllers/config.js (lines 30-32) inside getDistinctID replace the
throw with an immediate HTTP response like res.status(404).json({ error:
"Couldn't get data" }) (or equivalent JSON shape used elsewhere); in
src/api/controllers/config.js (lines 56-58) inside getConfigPool do the same
replacement with res.status(404).json({...}); and in
src/api/controllers/config.js (lines 81-83) inside getAllPools also replace the
throw with res.status(404).json({...}). Alternatively, if you prefer a single
centralized fix, update the errorHandler to honor AppError.statusCode and return
JSON (but do not do both); choose one approach and apply consistently to these
three sites.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: b39bd5c3-f0eb-4efa-b9c3-7a4b037e57ac
📒 Files selected for processing (1)
src/api/controllers/config.js
…eturning 500 with HTML
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/api/app.js`:
- Around line 57-58: The error handler currently returns err.message for all
responses which can leak internals for 5xx errors; change the response so that
after computing const statusCode = err.statusCode ?? 500 you use a conditional
message (e.g., const message = statusCode >= 500 ? 'Internal server error' :
err.message) and then call res.status(statusCode).json({ status: err.status ??
'error', message }); keep the existing status field behavior and only substitute
a generic message for server errors.
- Around line 55-59: The global Express error middleware function errorHandler
currently unconditionally writes a JSON response and can cause
ERR_HTTP_HEADERS_SENT if a response has already begun; add an early guard in
errorHandler that checks if res.headersSent and if so calls return next(err) to
delegate to the default/next error handler, otherwise continue to compute
statusCode and send the JSON response as before.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| function errorHandler (err, req, res, next) { | ||
| console.log(err) | ||
| res.status(500) | ||
| res.render('error', { error: err }) | ||
| const statusCode = err.statusCode ?? 500 | ||
| res.status(statusCode).json({ status: err.status ?? 'error', message: err.message }) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether error middleware already guards headersSent
rg -n -C3 'function errorHandler|headersSent|res\.status\(statusCode\)\.json' src/api/app.js
# Inspect error producers that can reach middleware
rg -n -C2 'throw new AppError|next\(err\)|Promise\.reject|throw ' src/api/controllers src/api/routes src/apiRepository: DefiLlama/yield-server
Length of output: 2117
🏁 Script executed:
#!/bin/bash
rg -n "class AppError|function AppError|statusCode|fail" src/api src/utils src -S
echo "----"
rg -n "res\.status\(400\)\.json|invalid uuid|UUID|uuid|Bad Request" src/api/controllers -SRepository: DefiLlama/yield-server
Length of output: 50379
🏁 Script executed:
#!/bin/bash
rg -n "class AppError|function AppError|statusCode|fail|status\s*=" src/api src/utils src -S
echo "----"
rg -n "res\.status\(400\)\.json|invalid uuid|UUID|uuid|Bad Request" src/api/controllers -SRepository: DefiLlama/yield-server
Length of output: 50379
Add a res.headersSent guard to the global Express error middleware
src/api/app.js’s errorHandler always calls res.status(...).json(...) without checking res.headersSent, so if a response has already started, Express can throw ERR_HTTP_HEADERS_SENT instead of delegating. Add an early if (res.headersSent) return next(err).
Suggested fix
function errorHandler (err, req, res, next) {
console.log(err)
+ if (res.headersSent) {
+ return next(err)
+ }
const statusCode = err.statusCode ?? 500
res.status(statusCode).json({ status: err.status ?? 'error', message: err.message })
}🤖 Prompt for 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.
In `@src/api/app.js` around lines 55 - 59, The global Express error middleware
function errorHandler currently unconditionally writes a JSON response and can
cause ERR_HTTP_HEADERS_SENT if a response has already begun; add an early guard
in errorHandler that checks if res.headersSent and if so calls return next(err)
to delegate to the default/next error handler, otherwise continue to compute
statusCode and send the JSON response as before.
| const statusCode = err.statusCode ?? 500 | ||
| res.status(statusCode).json({ status: err.status ?? 'error', message: err.message }) |
There was a problem hiding this comment.
Avoid returning raw internal error messages for 5xx responses.
At Line 58, message: err.message will expose internal failure details on unexpected server errors. Prefer a generic message for statusCode >= 500, while keeping specific messages for 4xx AppError flows.
Suggested fix
function errorHandler (err, req, res, next) {
console.log(err)
const statusCode = err.statusCode ?? 500
- res.status(statusCode).json({ status: err.status ?? 'error', message: err.message })
+ const message = statusCode >= 500 ? 'Internal server error' : err.message
+ res.status(statusCode).json({ status: err.status ?? 'error', message })
}🤖 Prompt for 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.
In `@src/api/app.js` around lines 57 - 58, The error handler currently returns
err.message for all responses which can leak internals for 5xx errors; change
the response so that after computing const statusCode = err.statusCode ?? 500
you use a conditional message (e.g., const message = statusCode >= 500 ?
'Internal server error' : err.message) and then call
res.status(statusCode).json({ status: err.status ?? 'error', message }); keep
the existing status field behavior and only substitute a generic message for
server errors.
in getConfigPool the invalid uuid early return was doing return { status: 'invalid uuid parameter' } which is just a plain JS object from the async function so express alw ignores this and no HTTP response is ever sent, and the client connection hangs until timeout
fixed by calling res.status(400).json(...) instead
Summary by CodeRabbit