-
Notifications
You must be signed in to change notification settings - Fork 153
introduce swaggo and rename swagger to swaggerui #1444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughSplits the original Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Swaggo as Swaggo Middleware
participant Swag as Swag Registry
participant FS as Static FS
Client->>Swaggo: GET /swag/index.html
Swaggo->>Swaggo: Render indexTmpl with Config
Swaggo-->>Client: 200 text/html
Client->>Swaggo: GET /swag/doc.json
Swaggo->>Swag: ReadDoc()
Swag-->>Swaggo: Swagger JSON
Swaggo-->>Client: 200 application/json
Client->>Swaggo: GET /swag/static/<asset>
Swaggo->>FS: Open asset
FS-->>Swaggo: bytes / error
Swaggo-->>Client: 200 (asset) / 404
Client->>Swaggo: GET /swag/ (with X-Forwarded-Prefix)
Swaggo->>Swaggo: Resolve prefix
Swaggo-->>Client: 301 redirect to /prefix/swag/index.html
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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 |
Summary of ChangesHello @ReneWerner87, 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 implements a significant refactoring by renaming the existing Highlights
Ignored Files
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request effectively renames the swagger module to swaggerdocgen and separates the swaggerui functionality. The changes are consistently applied across documentation, module paths, and configurations. I've identified a few minor issues, primarily typos in documentation and comments, along with a potential bug in the swaggerdocgen implementation that could introduce side effects. Additionally, I've suggested a small refactoring for improved code clarity. Overall, this is a well-executed refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
v3/swaggerdocgen/swagger_test.go (1)
90-124: Consider using testify/assert for consistency.The tests use custom assertion logic (e.g.,
t.Fatalfwith manual comparisons). While this works correctly, the codebase typically uses the testify/assert package for assertions, which would make the tests more readable and consistent.Example refactor using testify/assert:
+import ( + "github.com/stretchr/testify/assert" +) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { req, err := http.NewRequest(http.MethodGet, tt.url, nil) - if err != nil { - t.Fatal(err) - } + assert.NoError(t, err) resp, err := app.Test(req) - if err != nil { - t.Fatal(err) - } + assert.NoError(t, err) - if resp.StatusCode != tt.statusCode { - t.Fatalf(`StatusCode: got %v - expected %v`, resp.StatusCode, tt.statusCode) - } + assert.Equal(t, tt.statusCode, resp.StatusCode) if tt.contentType != "" { ct := resp.Header.Get("Content-Type") mediaType, _, err := mime.ParseMediaType(ct) - if err != nil { - t.Fatalf("invalid content type %q: %v", ct, err) - } - if mediaType != tt.contentType { - t.Fatalf(`Content-Type: got %s - expected %s`, mediaType, tt.contentType) - } + assert.NoError(t, err, "invalid content type %q", ct) + assert.Equal(t, tt.contentType, mediaType) } if tt.location != "" { location := resp.Header.Get("Location") - if location != tt.location { - t.Fatalf(`Location: got %s - expected %s`, location, tt.location) - } + assert.Equal(t, tt.location, location) } }) }Based on learnings
v3/swaggerdocgen/config.go (1)
281-319: Consider documenting boolean field default behavior.The
configDefaultfunction applies defaults for string and slice fields but cannot apply defaults for boolean fields likeDeepLinkingandShowMutatedRequestdue to Go's inability to distinguish between explicitly-setfalseand zero-valuefalse.This means if a user passes a partial config like
Config{Title: "My API"}, boolean fields will befalseinstead of the documented defaults (DeepLinking: true,ShowMutatedRequest: truefromConfigDefault).While this is a common limitation in Go APIs, consider adding a comment to document this behavior, or alternatively use pointer types (
*bool) for optional boolean fields to distinguish "not set" from "explicitly false".
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (10)
.github/workflows/test-swaggerdocgen.ymlis excluded by!**/*.yml.github/workflows/test-swaggerui.ymlis excluded by!**/*.ymlgo.workis excluded by!**/*.work,!**/*.workv3/swaggerdocgen/go.modis excluded by!**/*.modv3/swaggerdocgen/go.sumis excluded by!**/*.sum,!**/*.sumv3/swaggerui/go.modis excluded by!**/*.modv3/swaggerui/go.sumis excluded by!**/*.sum,!**/*.sumv3/swaggerui/swagger.jsonis excluded by!**/*.jsonv3/swaggerui/swagger.yamlis excluded by!**/*.yamlv3/swaggerui/swagger_missing.jsonis excluded by!**/*.json
📒 Files selected for processing (10)
README.md(1 hunks)v3/README.md(1 hunks)v3/swaggerdocgen/README.md(1 hunks)v3/swaggerdocgen/config.go(1 hunks)v3/swaggerdocgen/index.go(1 hunks)v3/swaggerdocgen/swagger.go(1 hunks)v3/swaggerdocgen/swagger_test.go(1 hunks)v3/swaggerui/README.md(3 hunks)v3/swaggerui/swagger.go(1 hunks)v3/swaggerui/swagger_test.go(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-02-07T10:18:09.439Z
Learnt from: SadikSunbul
Repo: gofiber/recipes PR: 2797
File: email-verification/main.go:26-31
Timestamp: 2025-02-07T10:18:09.439Z
Learning: In the gofiber/recipes repository, recipes should focus on demonstrating specific features clearly without production-level configurations like advanced error handling, graceful shutdown, or security middleware, as they are meant to be educational examples.
Applied to files:
v3/README.md
📚 Learning: 2025-10-16T07:15:26.529Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.
Applied to files:
v3/swaggerdocgen/swagger.gov3/swaggerui/README.md
📚 Learning: 2024-07-26T21:00:12.902Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The project uses the testify/assert package for assertions in unit tests.
Applied to files:
v3/swaggerdocgen/swagger_test.go
📚 Learning: 2025-10-16T07:19:52.418Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:19:52.418Z
Learning: In the Fiber codebase, the linter does not allow `require` assertions from within HTTP handlers (including net/http-style handlers). Use `t.Fatalf`, `t.Errorf`, or similar `testing.T` methods for error handling inside handler functions instead.
Applied to files:
v3/swaggerdocgen/swagger_test.go
🧬 Code graph analysis (3)
v3/swaggerdocgen/swagger.go (1)
v3/swaggerdocgen/config.go (1)
Config(8-186)
v3/swaggerdocgen/swagger_test.go (1)
v3/swaggerdocgen/swagger.go (2)
New(27-109)HandlerDefault(24-24)
v3/swaggerdocgen/config.go (1)
v3/swaggerui/swagger.go (2)
Config(19-68)ConfigDefault(71-78)
🔇 Additional comments (18)
v3/swaggerui/swagger.go (1)
1-1: LGTM! Package rename executed correctly.The package declaration has been successfully renamed from
swaggertoswaggerui, aligning with the PR's objective to clearly distinguish between the doc generator and UI components.v3/swaggerui/swagger_test.go (1)
1-1: LGTM! Test package rename aligns with the main package.The test package declaration has been correctly updated to
swaggerui, maintaining consistency with the main package rename.v3/README.md (1)
38-39: Documentation update looks good.The middleware list has been correctly updated to include both
swaggerdocgen(with the helpful "formerlyswagger" note) andswaggerui, along with their respective workflow badges.v3/swaggerdocgen/README.md (1)
1-144: Documentation looks comprehensive and well-structured.The README clearly documents:
- The rename from
swaggertoswaggerdocgenwith a prominent warning- Complete installation and usage instructions
- Configuration options with detailed descriptions
- References to the config.go file for complete implementation details
This will help users migrate from the old package name smoothly.
v3/swaggerdocgen/swagger_test.go (2)
43-125: Good test coverage for core functionality.The tests appropriately cover:
- HTML index rendering with correct content type
- JSON doc serving
- Static asset serving (favicon)
- Redirect behavior
- 404 handling
127-164: Good test for proxy prefix handling.The test validates that the
X-Forwarded-Prefixheader correctly influences redirect behavior, which is important for deployments behind reverse proxies.v3/swaggerui/README.md (1)
1-154: Documentation comprehensively updated for the package rename.The README has been thoroughly updated to reflect the
swaggeruipackage name, including:
- Updated package identifiers and titles
- Corrected import paths throughout all examples
- Updated API references (Config, New)
- Updated workflow badge references
- Maintained all example code with proper
swaggeruinamespaceThis ensures users will have clear, accurate documentation for the renamed package.
README.md (1)
40-41: No issues found — workflow files exist as referenced.Both workflow files (
test-swaggerdocgen.ymlandtest-swaggerui.yml) referenced in the README.md are present in.github/workflows/and correctly configured for the respective packages.v3/swaggerdocgen/index.go (2)
14-24: No XSS concerns—CustomStyle and CustomScript are properly typed and safe.The code correctly uses
template.CSSandtemplate.JStypes with Go'shtml/templatepackage (imported at swagger.go line 6). These special types are recognized by html/template and are not subject to escaping, which is the idiomatic Go pattern for safely injecting raw CSS and JavaScript into HTML templates. The type system itself ensures only valid CSS and JS content can be assigned to these fields.
57-57: Verify safe serialization of config object.Line 57 serializes the entire config object with
config = {{.}}. Ensure this doesn't inadvertently expose sensitive configuration details or create injection vulnerabilities.Verify that:
- The config struct is properly serialized to JSON
- No sensitive data (credentials, internal paths, etc.) is included in the config
- The serialization properly escapes JavaScript-sensitive characters
v3/swaggerdocgen/swagger.go (5)
1-24: LGTM!Package structure, imports, and constants are well-organized. The
HandlerDefaultinitialization is appropriate.
27-48: LGTM!The initialization logic is sound:
- Template parsing with appropriate panic for init-time failures
- Correct use of
sync.Onceto capture the base prefix once per handler instance- Proper handling of forwarded prefix for reverse proxy scenarios
50-68: LGTM!The routing logic correctly handles:
- Config cloning (shallow copy is sufficient since only the URL string field is modified)
- Index template rendering
- Dynamic doc generation via
swag.ReadDoc- Permanent redirect from root to index
69-107: LGTM!Static file serving implementation is solid:
- Proper path normalization and validation
- Correct error handling for missing files and directories
- Appropriate Content-Type detection from file extension
- Resource cleanup with deferred close
The use of
io.ReadAllis acceptable for Swagger UI assets, which are typically small.
111-134: Concatenation logic for multiple X-Forwarded-Prefix headers is undocumented and untested.The verification confirms your concern. The function iterates and concatenates all
X-Forwarded-Prefixheader values (line 119-126), but:
- X-Forwarded-Prefix is a de-facto non-standard header with implementation-specific behavior, not defined by any RFC standard
- Only one test case exists (single header value "/custom/path/"), with no coverage for multiple headers
- No inline comments explain why concatenation was chosen over alternatives (using first/last value)
The behavior for multi-proxy scenarios remains untested. Consider either:
- Adding tests for multiple header values to document expected behavior
- Adding a code comment explaining the concatenation choice
- Reconsidering the logic if concatenation isn't the intended behavior
v3/swaggerdocgen/config.go (3)
1-186: LGTM!The
Configstruct is comprehensive and well-documented:
- Appropriate use of
template.JSandtemplate.CSStypes for safe code injection- Clear default values documented for each field
- Proper JSON tags with strategic use of
omitemptyandjson:"-"
188-215: LGTM!The helper configuration types provide flexibility:
FilterConfig.Value()properly handles both boolean and string filter modesSyntaxHighlightConfig.Value()correctly returns the config object when activated orfalsewhen disabledThis design aligns with Swagger UI's configuration API.
256-278: LGTM!The
ConfigDefaultvariable provides sensible defaults for Swagger UI configuration, including appropriate plugins, presets, and UI behavior settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
.github/workflows/test-swaggo.ymlis excluded by!**/*.ymlgo.workis excluded by!**/*.work,!**/*.workv3/swaggo/go.modis excluded by!**/*.modv3/swaggo/go.sumis excluded by!**/*.sum,!**/*.sum
📒 Files selected for processing (7)
README.md(1 hunks)v3/README.md(1 hunks)v3/swaggo/README.md(1 hunks)v3/swaggo/config.go(1 hunks)v3/swaggo/index.go(1 hunks)v3/swaggo/swagger.go(1 hunks)v3/swaggo/swagger_test.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- README.md
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-02-07T10:18:09.439Z
Learnt from: SadikSunbul
Repo: gofiber/recipes PR: 2797
File: email-verification/main.go:26-31
Timestamp: 2025-02-07T10:18:09.439Z
Learning: In the gofiber/recipes repository, recipes should focus on demonstrating specific features clearly without production-level configurations like advanced error handling, graceful shutdown, or security middleware, as they are meant to be educational examples.
Applied to files:
v3/README.md
📚 Learning: 2024-11-23T19:50:41.765Z
Learnt from: norri
Repo: gofiber/recipes PR: 2701
File: clean-code/app/server/server.go:14-16
Timestamp: 2024-11-23T19:50:41.765Z
Learning: In the `clean-code` example at `clean-code/app/server/server.go` using the Go Fiber framework, it's acceptable to omit production-level features like context usage and graceful shutdown handling to keep the example simple.
Applied to files:
v3/README.md
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.
Applied to files:
v3/swaggo/README.mdv3/swaggo/swagger_test.go
📚 Learning: 2025-10-16T07:15:26.529Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.
Applied to files:
v3/swaggo/swagger.go
📚 Learning: 2024-07-26T21:00:12.902Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The project uses the testify/assert package for assertions in unit tests.
Applied to files:
v3/swaggo/swagger_test.go
📚 Learning: 2025-10-16T07:19:52.418Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:19:52.418Z
Learning: In the Fiber codebase, the linter does not allow `require` assertions from within HTTP handlers (including net/http-style handlers). Use `t.Fatalf`, `t.Errorf`, or similar `testing.T` methods for error handling inside handler functions instead.
Applied to files:
v3/swaggo/swagger_test.go
🧬 Code graph analysis (2)
v3/swaggo/swagger.go (1)
v3/swaggo/config.go (1)
Config(8-186)
v3/swaggo/swagger_test.go (1)
v3/swaggo/swagger.go (2)
New(27-109)HandlerDefault(24-24)
🪛 LanguageTool
v3/swaggo/README.md
[grammar] ~14-~14: Use a hyphen to join words.
Context: ...go/swag](https://github.com/swaggo/swag) generated documentation, and exposes hel...
(QB_NEW_EN_HYPHEN)
🔇 Additional comments (4)
v3/README.md (1)
38-39: Rename entry looks consistentLinks and workflow badges now track the swaggo / swaggerui split as expected.
v3/swaggo/README.md (1)
1-144: README covers the rename and API clearlyGood job documenting the new swaggo module, default handler, and configuration knobs so consumers can migrate smoothly.
v3/swaggo/swagger_test.go (1)
50-163: Great end-to-end coverageAppreciate the table-driven checks plus proxy-prefix scenario; this gives strong confidence in the handler.
v3/swaggo/swagger.go (1)
26-129: Handler flow looks solidTemplate parsing, prefix detection, doc serving, and asset fallback all read clean—once the template serialization fix lands, this will be ready.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
v3/swaggo/swagger.go (1)
50-53: Consider deep copying the config or making URL modification thread-safe.The shallow copy at line 50 means slices and pointers in
Config(e.g.,Plugins,Presets,OAuth) are shared across all requests. While only theURLstring field is modified here (which is safe), this pattern could lead to race conditions if future code modifies slice or pointer fields incfgCopy.Consider one of these approaches:
Option 1: Create a new Config struct for the modified URL
-cfgCopy := cfg -if len(cfgCopy.URL) == 0 { - cfgCopy.URL = path.Join(prefix, defaultDocURL) -} +url := cfg.URL +if len(url) == 0 { + url = path.Join(prefix, defaultDocURL) +} +cfgCopy := cfg +cfgCopy.URL = urlOption 2: Add a comment documenting the limitation
+// Shallow copy is safe since we only modify the URL string field cfgCopy := cfg
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
.github/workflows/golangci-lint.ymlis excluded by!**/*.yml
📒 Files selected for processing (1)
v3/swaggo/swagger.go(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-16T07:15:26.529Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.
Applied to files:
v3/swaggo/swagger.go
🧬 Code graph analysis (1)
v3/swaggo/swagger.go (1)
v3/swaggo/config.go (1)
Config(8-186)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: lint (swaggerui)
- GitHub Check: lint (swaggo)
🔇 Additional comments (4)
v3/swaggo/swagger.go (4)
1-17: LGTM!Package declaration and imports are appropriate for a Swagger UI middleware. All necessary dependencies are included.
19-24: LGTM!Constants and default handler initialization follow common Fiber middleware patterns.
55-68: LGTM!Request routing for index, doc.json, and root redirect is well-implemented. The use of
utils.CopyStringprevents holding references to Fiber's internal buffers, and the permanent redirect (301) for root paths is appropriate.
70-74: LGTM on security measures!The path cleaning with
path.Cleanand the directory check provide good protection against directory traversal attacks and prevent directory listing.Also applies to: 98-100
| defer func() { | ||
| cerr := file.Close() | ||
| if cerr != nil && err == nil { | ||
| err = cerr | ||
| } | ||
| }() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix: Deferred close error is silently lost.
The deferred function attempts to capture file.Close() errors by assigning to err, but this assignment has no effect because the handler function func(c fiber.Ctx) error does not use named return values. Close errors will be silently ignored.
Apply this diff to properly propagate close errors using named returns:
-return func(c fiber.Ctx) error {
+return func(c fiber.Ctx) (err error) {
once.Do(func() {
basePrefix = strings.ReplaceAll(c.Route().Path, "*", "")
})And update the template parsing error variable to avoid shadowing:
- index, err := template.New("swagger_index.html").Parse(indexTmpl)
- if err != nil {
- panic(fmt.Errorf("fiber: swagger middleware error -> %w", err))
+ index, parseErr := template.New("swagger_index.html").Parse(indexTmpl)
+ if parseErr != nil {
+ panic(fmt.Errorf("fiber: swagger middleware error -> %w", parseErr))
}And at line 63:
case defaultDocURL:
- var doc string
- if doc, err = swag.ReadDoc(cfgCopy.InstanceName); err != nil {
+ doc, err := swag.ReadDoc(cfgCopy.InstanceName)
+ if err != nil {
return err
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In v3/swaggo/swagger.go around lines 83 to 88 (and update at line 63), the
deferred file.Close() error is being assigned to a non-existent named return
variable so close errors are lost; change the handler signature to use a named
return (e.g., func(c fiber.Ctx) (err error)) and in the defer assign cerr to err
only when err == nil to propagate Close errors, and also rename the template
parsing error variable at line 63 to avoid shadowing the named return (use a
different local variable name like tplErr) so you don't accidentally shadow the
handler's err.
Summary
Testing
https://chatgpt.com/codex/tasks/task_e_6904abffa6448326a0e1654ec815e31d
Summary by CodeRabbit
New Features
Documentation
Tests