🔥 feat: Add PanicHandler in recover middleware#4110
Conversation
Summary of ChangesHello @JonasDoe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds an Changes
Sequence Diagram(s)mermaid Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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.
Pull request overview
Adds an ErrorCustomizer hook to Fiber’s recover middleware so callers can sanitize/replace errors produced from recovered panics before they reach the app-level ErrorHandler.
Changes:
- Introduces
Config.ErrorCustomizerwith a default implementation. - Updates recover middleware to call the customizer when a non-
errorpanic value is recovered. - Updates
recovermiddleware unit test to exercise the new config surface.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| middleware/recover/config.go | Adds ErrorCustomizer to recover.Config and wires it into ConfigDefault. |
| middleware/recover/recover.go | Adds default customizer and uses it when recovering non-error panic values. |
| middleware/recover/recover_test.go | Updates the main recover test to configure ErrorCustomizer and changes expected behavior. |
There was a problem hiding this comment.
Code Review
This pull request enhances the recover middleware by introducing an ErrorCustomizer to allow users to mask internal panic details and prevent leaking implementation specifics. However, a critical vulnerability exists: if a partial Config struct is provided, the ErrorCustomizer field can remain uninitialized (nil), leading to a nil pointer dereference and an application panic, which can be exploited for a Denial of Service. Additionally, the current logic bypasses the customizer if the panic value is already an error, limiting its usefulness, and the configDefault helper is missing a crucial nil-check for the new field. There's also a mismatch in the provided test case between the customizer and its assertions.
|
@JonasDoe Please check the comments above. There's a few issues with the implementation.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@middleware/recover/recover_test.go`:
- Around line 16-24: The test currently uses require.Equal inside the
ErrorHandler closure which violates the linter rule against assertions in HTTP
handlers and also compares against the panic string while ErrorCustomizer
returns fiber.ErrInternalServerError; change the handler to remove require and
instead call t.Errorf to report failures, and assert that err equals
fiber.ErrInternalServerError (or err == fiber.ErrInternalServerError) rather
than the panic message; update the ErrorHandler closure and its assertion
accordingly so the handler reports via t.Errorf and validates the error from
ErrorCustomizer.
In `@middleware/recover/recover.go`:
- Around line 38-42: The panic recovery path calls cfg.ErrorCustomizer without
checking for nil, which can cause a secondary panic on non-error panics; update
configDefault() to set a default ErrorCustomizer (same pattern used for
StackTraceHandler) so ErrorCustomizer is never nil, or alternatively add a
nil-check before calling cfg.ErrorCustomizer in the recover logic (the code
around ErrorCustomizer and r.(error) in recover.go) to only call it when non-nil
and otherwise set a sensible default error value.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
middleware/recover/config.gomiddleware/recover/recover.gomiddleware/recover/recover_test.go
There was a problem hiding this comment.
♻️ Duplicate comments (1)
middleware/recover/recover_test.go (1)
16-24:⚠️ Potential issue | 🔴 Critical
requireinsideErrorHandlerviolates the linter rule, and the assertion compares the wrong error.Two unresolved problems in
Test_Recover:
- Linter violation –
require.Equalinside theErrorHandlerclosure panics the test goroutine on failure instead of failing the test; uset.Errorfinside handlers.- Wrong assertion – The custom
ErrorCustomizerreturnsfiber.ErrInternalServerError, soErrorHandlerreceives that error ("Internal Server Error"), not the panic string. The assertion against"[RECOVERED]: Hi, I'm an error!"will always fail.🐛 Proposed fix
ErrorHandler: func(c fiber.Ctx, err error) error { - require.Equal(t, "[RECOVERED]: Hi, I'm an error!", err.Error()) + if err == nil || err.Error() != fiber.ErrInternalServerError.Error() { + t.Errorf("expected %q, got %v", fiber.ErrInternalServerError.Error(), err) + } return c.SendStatus(fiber.StatusTeapot) },Based on learnings: in the Fiber codebase, the linter does not allow
requireassertions from within HTTP handlers; uset.Fatalf,t.Errorf, or similartesting.Tmethods instead.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@middleware/recover/recover_test.go` around lines 16 - 24, Test_Recover's ErrorHandler closure uses require.Equal (which panics) and asserts the wrong string; replace the require call inside the ErrorHandler with a testing.T method (e.g., t.Errorf or t.Fatalf) to avoid panicking the test goroutine, and change the asserted error text to match the ErrorCustomizer return value (fiber.ErrInternalServerError.Error()) so ErrorHandler checks for "Internal Server Error" instead of "[RECOVERED]: Hi, I'm an error!"; locate the closure passed as ErrorHandler in Test_Recover and update the assertion and assertion helper accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@middleware/recover/recover_test.go`:
- Around line 16-24: Test_Recover's ErrorHandler closure uses require.Equal
(which panics) and asserts the wrong string; replace the require call inside the
ErrorHandler with a testing.T method (e.g., t.Errorf or t.Fatalf) to avoid
panicking the test goroutine, and change the asserted error text to match the
ErrorCustomizer return value (fiber.ErrInternalServerError.Error()) so
ErrorHandler checks for "Internal Server Error" instead of "[RECOVERED]: Hi, I'm
an error!"; locate the closure passed as ErrorHandler in Test_Recover and update
the assertion and assertion helper accordingly.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
middleware/recover/config.gomiddleware/recover/recover_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- middleware/recover/config.go
There was a problem hiding this comment.
♻️ Duplicate comments (1)
middleware/recover/recover_test.go (1)
18-19:⚠️ Potential issue | 🟠 MajorAvoid
requireinside ErrorHandler closures.Same issue as previously flagged: the linter disallows
require.*in HTTP handlers. Uset.Errorf(or similar) inside the handler instead.Based on learnings: In the Fiber codebase, the linter does not allow
requireassertions from within HTTP handlers (including net/http-style handlers).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@middleware/recover/recover_test.go` around lines 18 - 19, The test's ErrorHandler closure uses require.Equal inside the HTTP handler (require.Equal(..., err.Error())), which the linter forbids; replace that require call with t.Errorf (or t.Fatalf) to report the mismatch from the handler instead of calling require, e.g., compare err.Error() to the expected string and call t.Errorf with a descriptive message if it differs, leaving the rest of the handler (return c.SendStatus(fiber.StatusTeapot)) unchanged so the test still exercises the response path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@middleware/recover/recover_test.go`:
- Around line 18-19: The test's ErrorHandler closure uses require.Equal inside
the HTTP handler (require.Equal(..., err.Error())), which the linter forbids;
replace that require call with t.Errorf (or t.Fatalf) to report the mismatch
from the handler instead of calling require, e.g., compare err.Error() to the
expected string and call t.Errorf with a descriptive message if it differs,
leaving the rest of the handler (return c.SendStatus(fiber.StatusTeapot))
unchanged so the test still exercises the response path.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
middleware/recover/config.gomiddleware/recover/recover.gomiddleware/recover/recover_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- middleware/recover/recover.go
5b7117e to
567bcd8
Compare
Hey @gaby , thank you for the fast reply. Some questions:
|
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
middleware/recover/recover_test.go (1)
17-21:⚠️ Potential issue | 🔴 Critical
require.Equalinside the ErrorHandler violates the linter rule.The
requireassertion on line 18 is inside afiber.Ctx-typed handler closure. The linter forbidsrequirecalls within HTTP handlers; uset.Errorfinstead.✅ Proposed fix
ErrorHandler: func(c fiber.Ctx, err error) error { - require.Equal(t, "[RECOVERED]: Hi, I'm an error!", err.Error()) + if err == nil || err.Error() != "[RECOVERED]: Hi, I'm an error!" { + t.Errorf("expected %q, got %v", "[RECOVERED]: Hi, I'm an error!", err) + } return c.SendStatus(fiber.StatusTeapot) },Based on learnings: "the linter does not allow
requireassertions from within HTTP handlers (including net/http-style handlers). Uset.Fatalf,t.Errorf, or similartesting.Tmethods for error handling inside handler functions instead."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@middleware/recover/recover_test.go` around lines 17 - 21, The test handler's ErrorHandler closure uses require.Equal (inside the anonymous func(c fiber.Ctx, err error) error) which violates the linter for HTTP handlers; replace the require call with a testing.T method (e.g., t.Errorf or t.Fatalf) to report the mismatch—check that err.Error() equals "[RECOVERED]: Hi, I'm an error!" using t.Errorf/fatal and then return c.SendStatus(fiber.StatusTeapot) as before so the assertion runs without using require inside ErrorHandler.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/whats_new.md`:
- Around line 1591-1594: Fix the grammar in the Recover section: change the
possessive "it's `Config`" to "its `Config`" and change the article "Set a
`ErrorCustomizer`" to "Set an `ErrorCustomizer`"; update the sentence
referencing the Recover middleware, its `Config`, and the `ErrorCustomizer`
symbol accordingly.
- Around line 1591-1594: Update the Config documentation table in
docs/middleware/recover.md to include the missing ErrorCustomizer field
referenced by Recover and whats_new.md: add a row for ErrorCustomizer with Type
`func(fiber.Ctx, any) error`, Description "Customize the error returned from a
recovered panic.", and Default `defaultErrorCustomizer`; ensure it is placed
alongside Next, EnableStackTrace, and StackTraceHandler and uses the exact
symbol names ErrorCustomizer and defaultErrorCustomizer so the public API docs
match the implementation and whats_new.md mention.
---
Duplicate comments:
In `@middleware/recover/recover_test.go`:
- Around line 17-21: The test handler's ErrorHandler closure uses require.Equal
(inside the anonymous func(c fiber.Ctx, err error) error) which violates the
linter for HTTP handlers; replace the require call with a testing.T method
(e.g., t.Errorf or t.Fatalf) to report the mismatch—check that err.Error()
equals "[RECOVERED]: Hi, I'm an error!" using t.Errorf/fatal and then return
c.SendStatus(fiber.StatusTeapot) as before so the assertion runs without using
require inside ErrorHandler.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/whats_new.mdmiddleware/recover/config.gomiddleware/recover/recover.gomiddleware/recover/recover_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
- middleware/recover/config.go
- middleware/recover/recover.go
ErrorCustomizer in recover middleware- Exposed DefaultPanicHandler since it might be useful for the users
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a PanicHandler to the recover middleware, enabling customization of errors generated from panics. The changes are well-implemented across the middleware's configuration, logic, tests, and documentation. My review includes suggestions to improve the clarity and consistency of the documentation's code examples and to enhance code maintainability by aligning struct literal field order with the struct definition.
|
@JonasDoe Few docs issues, and update the PR description. Other than that, it looks good. |
|
@ReneWerner87 Do you remember why the docs are importing as recoverer ? |
I don't remember, |
|
Congrats on merging your first pull request! 🎉 We here at Fiber are proud of you! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord |
Description
If added an
PanicHandlerfield to theConfigof therecovermiddleware. Thre reason: Right now,panicsrecovered by the middleware will expose internals when they get returned. While theErrorHandlerin thefiber.Configallows me to change this behavior, at this point I've no way to actually detect whether theerroris intended to be returned int he response or not.With the
PanicHandler, I can create return a dedicated, internalerrortype so theErrorHandlerknow to handle it differently, or I can return anerrorwhich got already cleared of all internals.Fixes #4109
Changes introduced
List the new features or adjustments introduced in this pull request. Provide details on benchmarks, documentation updates, changelog entries, and if applicable, the migration guide.
PanicHandlerfor therecovermiddleware.errorsdon't mirror JavaScriptErrorsanyway.Type of change
Please delete options that are not relevant.
Checklist
Before you submit your pull request, please make sure you meet these requirements:
/docs/directory for Fiber's documentation.ok github.com/gofiber/fiber/v3/middleware/recover 0.015s