Skip to content

🐛 bug: Fix maintain CustomCtx across middlewares#3852

Merged
ReneWerner87 merged 3 commits intomainfrom
codex/2025-11-08-16-06-53
Nov 10, 2025
Merged

🐛 bug: Fix maintain CustomCtx across middlewares#3852
ReneWerner87 merged 3 commits intomainfrom
codex/2025-11-08-16-06-53

Conversation

@ReneWerner87
Copy link
Member

Summary

  • store the active custom context on the request context so middleware continuations retain the caller's type
  • load and clear the staged custom context during Reset and release
  • set up the staged custom context in AcquireCtx before invoking Reset

Testing

  • make audit (fails: govulncheck cannot reach vuln.go.dev, returns 403)
  • make generate
  • make betteralign
  • make modernize
  • make format
  • make test

Codex Task

Copilot AI review requested due to automatic review settings November 8, 2025 16:06
@ReneWerner87 ReneWerner87 requested a review from a team as a code owner November 8, 2025 16:06
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Note

Other AI code review bot(s) detected

CodeRabbit 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.

Walkthrough

Adds per-request custom context support: DefaultCtx gains an unexported handlerCtx CustomCtx field; routing (Next/RestartRouting) and context acquisition now prefer an active custom context when present; helper to set/clear handler context added; tests exercise middleware visibility of custom ctx.

Changes

Cohort / File(s) Summary
Core ctx and routing
ctx.go
Add unexported handlerCtx CustomCtx to DefaultCtx; replace hard-coded user key with iota-based key; add setHandlerCtx, activeHandler/continueHandlers logic; route advance and RestartRouting now choose custom handler chain when active; Release/reset clear handlerCtx.
Ctx interface generation
ctx_interface_gen.go
Add setHandlerCtx(ctx CustomCtx) method to the generated Ctx interface.
Context acquisition
ctx_interface.go
App.AcquireCtx performs a runtime assertion for the setter interface and calls setHandlerCtx on acquired ctx (before Reset) to attach per-request CustomCtx.
App config flag
app.go
Add hasCustomCtx bool to App and update setCtxFunc to set the flag based on presence of a custom ctx factory.
Tests
ctx_test.go
Add Test_Ctx_CustomCtx_WithMiddleware to ensure middleware and handlers observe the custom context type and behavior.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant App
    participant Acquire as AcquireCtx
    participant Ctx as DefaultCtx
    participant Handlers as HandlerChain

    Client->>App: HTTP request
    App->>Acquire: AcquireCtx()
    Acquire-->>Ctx: provide DefaultCtx (may hold CustomCtx)
    alt handlerCtx (CustomCtx) present
        Note right of Ctx `#a2d5c6`: active handlerCtx used
        Ctx->>Handlers: continueHandlers() -> app.nextCustom(path with CustomCtx)
        Handlers->>Ctx: handler invoked with CustomCtx via activeHandler()
    else no CustomCtx
        Note right of Ctx `#f3e8c6`: default flow
        Ctx->>Handlers: continueHandlers() -> app.next (standard)
        Handlers->>Ctx: handler invoked with DefaultCtx
    end
    Handlers->>Client: response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • correctness and nil-safety of setHandlerCtx and activeHandler semantics
    • ordering in AcquireCtx (calling setter before Reset)
    • branching between app.next and app.nextCustom in handler continuation
    • impact of generated interface change on other implementations

Possibly related PRs

Suggested labels

✏️ Feature

Suggested reviewers

  • gaby
  • sixcolors
  • efectn

Poem

🐰 I tuck a custom ctx in my paw,

Hopping through middleware, neat and raw.
Next knows the path I quietly keep,
Restart and handlers wake from sleep.
A tiny hop — my context runs deep!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description provides a clear summary of changes (storage, loading, clearing of custom context) and lists comprehensive testing steps performed, but lacks details on several template sections like benchmarks, documentation updates, and migration guidance.
Title check ✅ Passed The title refers to maintaining custom context across middlewares, which is a core objective reflected in the PR summary and implementation changes across ctx.go, ctx_interface.go, and app.go.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/2025-11-08-16-06-53

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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 addresses an issue where custom context implementations were not consistently maintained across middleware continuations in the application's request handling flow. By introducing mechanisms to store, load, and clear the active custom context within the DefaultCtx and updating the context acquisition and progression methods, the changes ensure that custom context types are correctly propagated to all handlers and middleware, preserving their specific functionalities throughout the request lifecycle.

Highlights

  • Custom Context Propagation: Ensures that custom context implementations are correctly passed through middleware and subsequent handlers, preventing type loss during request processing.
  • DefaultCtx Enhancement: Introduced a customCtx field within the DefaultCtx struct to store the active custom context, allowing it to be consistently referenced.
  • Context Lifecycle Management: Implemented logic in AcquireCtx, Reset, Next, RestartRouting, and release methods to properly stage, load, and clear the custom context throughout the request's lifecycle.
  • New Test Case: Added Test_Ctx_CustomCtx_WithMiddleware to validate the correct propagation and type assertion of custom contexts when used with middleware.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Nov 8, 2025

Codecov Report

❌ Patch coverage is 59.09091% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.11%. Comparing base (a602d63) to head (e340afc).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
ctx.go 50.00% 6 Missing and 3 partials ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3852   +/-   ##
=======================================
  Coverage   92.10%   92.11%           
=======================================
  Files         115      115           
  Lines        9754     9774   +20     
=======================================
+ Hits         8984     9003   +19     
  Misses        490      490           
- Partials      280      281    +1     
Flag Coverage Δ
unittests 92.11% <59.09%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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 introduces a mechanism to maintain a custom context across middleware handlers. The changes involve storing the custom context on the fasthttp.RequestCtx and then loading it into the Fiber Ctx during its lifecycle. The implementation looks correct and is supported by a new test case. I've provided a couple of suggestions to improve code maintainability and idiomatic Go usage.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for custom context implementations to work correctly with middleware in Fiber. Previously, custom contexts were not properly passed through middleware chains, causing type assertion failures and incorrect behavior.

  • Introduces a handlerContextKey to track custom context instances through the request lifecycle
  • Modifies the Next() and RestartRouting() methods to properly route through custom context handlers
  • Adds comprehensive test coverage for custom context behavior with middleware

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
ctx_interface.go Stores custom context reference in fasthttp request context during acquisition to enable proper routing
ctx.go Adds custom context tracking field and constants, updates Next/RestartRouting to use custom handlers when appropriate, manages custom context lifecycle in Reset/release
ctx_test.go Adds test validating custom context works correctly with middleware chains

@ReneWerner87 ReneWerner87 added the v3 label Nov 8, 2025
@ReneWerner87 ReneWerner87 added this to v3 Nov 8, 2025
@ReneWerner87 ReneWerner87 added this to the v3 milestone Nov 8, 2025
@ReneWerner87 ReneWerner87 linked an issue Nov 8, 2025 that may be closed by this pull request
3 tasks
@ReneWerner87

This comment was marked as outdated.

@ReneWerner87

This comment was marked as outdated.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de39792 and 11b70ba.

📒 Files selected for processing (3)
  • ctx.go (3 hunks)
  • ctx_interface.go (1 hunks)
  • ctx_interface_gen.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ctx_interface.go
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Apply formatting using gofumpt (Make target: format)
Optimize struct field alignment using betteralign (Make target: betteralign)
Modernize code using gopls modernize (Make target: modernize)

Files:

  • ctx.go
  • ctx_interface_gen.go
🧠 Learnings (4)
📓 Common learnings
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.
📚 Learning: 2024-11-08T04:10:42.990Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.

Applied to files:

  • ctx.go
  • ctx_interface_gen.go
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • ctx.go
  • ctx_interface_gen.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/session/config.go:122-122
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In `DefaultErrorHandler(c *fiber.Ctx, err error)`, since `c` is a pointer to an interface, we need to dereference `*c` when calling interface methods like `SendStatus`.

Applied to files:

  • ctx.go
🧬 Code graph analysis (2)
ctx.go (2)
ctx_interface.go (1)
  • CustomCtx (15-35)
ctx_interface_gen.go (1)
  • Ctx (18-431)
ctx_interface_gen.go (1)
ctx_interface.go (1)
  • CustomCtx (15-35)
⏰ 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). (6)
  • GitHub Check: lint
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: unit (1.25.x, macos-13)
  • GitHub Check: repeated
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: Compare

@ReneWerner87

This comment was marked as outdated.

@ReneWerner87
Copy link
Member Author

last change is the fastest i can produce

goos: darwin
goarch: arm64
pkg: github.com/gofiber/fiber/v3
cpu: Apple M2 Pro
                                           │ main-branch.txt │           new4-branch.txt           │
                                           │     sec/op      │    sec/op     vs base               │
_Router_NotFound-12                             257.8n ±  1%   258.4n ±  1%       ~ (p=0.382 n=10)
_Router_Handler-12                              76.98n ±  2%   79.37n ±  1%  +3.10% (p=0.002 n=10)
_Router_Handler_Strict_Case-12                  72.21n ±  2%   72.91n ±  0%       ~ (p=0.190 n=10)
_Router_Chain-12                                177.1n ±  1%   176.6n ±  0%       ~ (p=0.362 n=10)
_Router_WithCompression-12                      175.9n ±  1%   176.9n ±  0%  +0.60% (p=0.006 n=10)
_Router_Next-12                                 44.21n ±  1%   44.27n ±  1%       ~ (p=0.342 n=10)
_Router_Next_Default-12                         32.73n ±  0%   33.36n ±  0%  +1.92% (p=0.001 n=10)
_Router_Next_Default_Parallel-12                4.629n ± 25%   4.522n ± 15%       ~ (p=0.684 n=10)
_Router_Next_Default_Immutable-12               33.71n ±  1%   34.29n ±  0%  +1.71% (p=0.001 n=10)
_Router_Next_Default_Parallel_Immutable-12      5.373n ± 16%   4.900n ± 12%       ~ (p=0.218 n=10)
_Router_Handler_CaseSensitive-12                72.40n ±  2%   73.32n ± 10%  +1.27% (p=0.046 n=10)
_Router_Handler_Unescape-12                     109.2n ±  3%   108.9n ±  0%       ~ (p=0.515 n=10)
_Router_Handler_StrictRouting-12                73.13n ±  2%   73.46n ±  9%       ~ (p=0.149 n=10)
_Router_GitHub_API-12                           40.82µ ±  8%   44.27µ ± 15%       ~ (p=0.075 n=10)
geomean                                         86.33n         86.72n        +0.45%

                                           │ main-branch.txt │           new4-branch.txt           │
                                           │      B/op       │    B/op     vs base                 │
_Router_NotFound-12                             8.000 ± 0%     8.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default-12                         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default_Parallel-12                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default_Immutable-12               0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default_Parallel_Immutable-12      0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
geomean                                                    ²               +0.00%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                           │ main-branch.txt │           new4-branch.txt           │
                                           │    allocs/op    │ allocs/op   vs base                 │
_Router_NotFound-12                             1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default-12                         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default_Parallel-12                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default_Immutable-12               0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
_Router_Next_Default_Parallel_Immutable-12      0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=10) ¹
geomean                                                    ²               +0.00%                ²

@ksw2000 @arturmelanchyk do you have ideas to improve this ?

@gaby gaby changed the title Maintain custom context across middleware 🐛 bug: Fix maintain CustomCtx across middlewares Nov 9, 2025
github-actions[bot]

This comment was marked as off-topic.

@gaby gaby added the ☢️ Bug label Nov 9, 2025
@arturmelanchyk
Copy link
Contributor

nothing I can think of

@ReneWerner87 ReneWerner87 merged commit 5e596e3 into main Nov 10, 2025
19 of 22 checks passed
@ReneWerner87 ReneWerner87 deleted the codex/2025-11-08-16-06-53 branch November 10, 2025 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

🐛 [Bug]: app.Use breaks when using NewWithCustomCtx

4 participants