Skip to content

Conversation

@gaby
Copy link
Member

@gaby gaby commented Aug 29, 2025

Summary

  • allow obtaining a standalone context.Context from Fiber's Ctx via new Context() and SetContext helpers
  • document that fiber.Ctx is recycled and show how to use the new context for async work
  • mention the new helpers in the changelog and add tests
  • ensure Ctx.Context() panics if invoked after the handler and add unit tests covering context reuse

Fixes #3718

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 29, 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 stdlib context support to Ctx via fasthttp UserValue with new Context() and SetContext() methods; clears stored context on Reset. Updates Ctx interface, docs, tests, and modifies timeout middleware to derive, set, and restore timeout-bound contexts.

Changes

Cohort / File(s) Summary
Core Ctx context storage
ctx.go
Adds unexported user-value key and implements Context() context.Context and SetContext(ctx context.Context) on DefaultCtx; lazily initializes to context.Background() and clears the stored context in Reset.
Ctx interface updates
ctx_interface_gen.go
Extends Ctx interface with Context() context.Context and SetContext(context.Context) (imports context).
Core tests
ctx_test.go
Adds tests for Context()/SetContext() lifecycle, per-request isolation across app.Test, panic-on-access after handler completion, and Locals generics behavior.
Docs: API and guides
docs/api/ctx.md, docs/guide/context.md, docs/whats_new.md
Documents Context()/SetContext() usage, cautions about Ctx lifetime, provides async examples and guidance; updates changelog/what's new.
Middleware: timeout behavior
middleware/timeout/timeout.go
Timeout middleware now derives parent via c.Context(), creates tCtx with context.WithTimeout(parent, d), calls c.SetContext(tCtx) for handler use, restores parent and cancels after handler, and inspects tCtx.Err() to detect timeouts and call OnTimeout.
Middleware tests
middleware/timeout/timeout_test.go
Tests updated to use c.Context() in helpers, add timing assertions for cancellation, and assert OnTimeout invocation behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Fiber
  participant TimeoutMW as Timeout Middleware
  participant Handler as User Handler
  participant Ctx as fiber.Ctx
  participant StdCtx as std context

  Client->>Fiber: HTTP request
  Fiber->>TimeoutMW: enter middleware
  TimeoutMW->>Ctx: parent := Ctx.Context()
  TimeoutMW->>StdCtx: tCtx, cancel := context.WithTimeout(parent, duration)
  TimeoutMW->>Ctx: Ctx.SetContext(tCtx)
  TimeoutMW->>Handler: call next (handler)
  Handler-->>TimeoutMW: return (may spawn goroutines using Ctx.Context())
  TimeoutMW->>StdCtx: check tCtx.Err()
  alt timeout occurred
    TimeoutMW-->>Fiber: invoke OnTimeout (propagate error or ErrRequestTimeout)
  else completed
    TimeoutMW-->>Fiber: forward handler result
  end
  TimeoutMW->>StdCtx: cancel()
  TimeoutMW->>Ctx: Ctx.SetContext(parent)  %% restore parent context
  Fiber-->>Client: response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Provide/document a safe std context to use outside handler lifetime (#3718)
Ensure per-request context isolation; no leakage across requests (#3718)
Update middleware to propagate/observe cancellation via std context (#3718)
Prevent panic when using fiber.Ctx itself as context.Context after handler returns (#3718) The change provides a separate safe std context via Context()/SetContext() but does not make fiber.Ctx safe to use as a context.Context after handler completion; DefaultCtx.Value may still access RequestCtx and panic if used after reuse.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Added tests for Locals generics (ctx_test.go) These tests exercise generic Locals behavior and are not required to address the linked issue (#3718) about safe std context and preventing panics; they introduce extra test coverage unrelated to the core objective.

Possibly related PRs

Suggested reviewers

  • sixcolors
  • efectn

"I hop through handlers, swift and bright,
Tucking a context, snug and tight.
Timeouts nibble, clocks go tick—
I swap and cancel, whisker-quick.
No leaks, no panic, carrot won. 🥕"

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch document-context.context-limitations-and-add-support

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Aug 29, 2025

Codecov Report

❌ Patch coverage is 95.23810% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 92.02%. Comparing base (e878cd8) to head (62e429c).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
middleware/timeout/timeout.go 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3720      +/-   ##
==========================================
- Coverage   92.08%   92.02%   -0.06%     
==========================================
  Files         115      115              
  Lines       11535    11550      +15     
==========================================
+ Hits        10622    10629       +7     
- Misses        662      668       +6     
- Partials      251      253       +2     
Flag Coverage Δ
unittests 92.02% <95.23%> (-0.06%) ⬇️

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.

@gaby gaby changed the title Add persistent context and document async caveat 🐛 bug: Fix support for context.Context Aug 29, 2025
@gaby gaby added this to v3 Aug 29, 2025
@gaby gaby added this to the v3 milestone Aug 29, 2025
@gaby gaby moved this to In Progress in v3 Aug 29, 2025
@gaby gaby marked this pull request as ready for review August 29, 2025 20:48
Copilot AI review requested due to automatic review settings August 29, 2025 20:48
@gaby gaby requested a review from a team as a code owner August 29, 2025 20:48
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 obtaining a standalone context.Context from Fiber's Ctx via new Context() and SetContext() methods. This addresses the issue that fiber.Ctx is recycled after each request and cannot be safely used in asynchronous operations that outlive the handler.

Key changes:

  • Adds Context() and SetContext() methods to fiber.Ctx for safe async context handling
  • Updates timeout middleware to use the new context methods for proper timeout propagation
  • Adds comprehensive documentation and tests for the new functionality

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
ctx.go Implements the new Context() and SetContext() methods with proper context storage and reset
ctx_interface_gen.go Adds the new context methods to the Ctx interface
ctx_test.go Adds comprehensive tests for context handling, including panic behavior and multi-request scenarios
middleware/timeout/timeout.go Updates timeout middleware to use new context methods for proper timeout context propagation
middleware/timeout/timeout_test.go Updates tests to use c.Context() and adds timing assertions
docs/api/ctx.md Documents the new Context() and SetContext() methods with examples
docs/guide/context.md Adds guidance on using context outside handlers and async work patterns
docs/whats_new.md Updates changelog with new methods and migration guidance

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

Codex Review: Here are some suggestions.

Reply with @codex fix comments to fix any unresolved comments.

About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".

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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ctx.go (1)

398-402: Avoid nil-pointer panic in Value() after handler return

Accessing c.Value after return will NPE today. Fail fast with a clear message. This directly addresses the panic reported in #3718.

 func (c *DefaultCtx) Value(key any) any {
-	return c.fasthttp.UserValue(key)
+	if c.fasthttp == nil {
+		panic("fiber: Ctx.Value() called after handler returned; do not use Ctx outside handler")
+	}
+	return c.fasthttp.UserValue(key)
 }
🧹 Nitpick comments (13)
ctx_interface_gen.go (2)

23-26: Fix misleading RequestCtx comment

fasthttp.RequestCtx doesn’t “carry a deadline/cancellation signal” like context.Context. Reword to “returns the underlying *fasthttp.RequestCtx”.

- // RequestCtx returns *fasthttp.RequestCtx that carries a deadline
- // a cancellation signal, and other values across API boundaries.
+ // RequestCtx returns the underlying *fasthttp.RequestCtx.

26-31: Document lifecycle constraint and panic semantics for Context()/SetContext()

Per PR goal, Context() should not be callable after the handler returns. Reflect this in interface docs.

- // Context returns a context implementation that was set by
- // user earlier or returns a non-nil, empty context, if it was not set earlier.
+ // Context returns the per-request base context previously set via SetContext,
+ // or a non-nil empty context if none was set.
+ // Panics if called after the handler returns (Ctx is recycled).
 
- // SetContext sets a context implementation by user.
+ // SetContext sets the base context returned by Context(). Call only during
+ // the handler's lifetime.
ctx.go (2)

461-461: Nit: ensure removal vs niling of user context

If fasthttp exposes a RemoveUserValue, prefer it to avoid leaving a nil entry; otherwise this is fine.


34-36: Consider removing DefaultCtx’s context.Context implementation
The compile-time assertion _ context.Context = (*DefaultCtx)(nil) still allows passing Ctx to context.With*, but our scan found no direct misuse (only context.WithTimeout(c.ctx, …)). Dropping this assertion would discourage future misuse while explicit panics already guard incorrect calls.

docs/whats_new.md (1)

485-487: Clarify safe usage and panic behavior for Context helpers

Add an explicit caution that Ctx is recycled and that calling Context() after return panics; recommend capturing ctx inside the handler for async work.

- - **Context()**: Returns a `context.Context` that can be used outside the handler.
- - **SetContext**: Sets the base `context.Context` returned by `Context()` for propagating deadlines or values.
+ - **Context()**: Returns a `context.Context` you can capture inside the handler and safely use outside it.
+ - **SetContext**: Sets the base `context.Context` returned by `Context()` for propagating deadlines or values.
+   - Caution: `fiber.Ctx` is recycled. Calling `c.Context()` after the handler returns panics. Always call `ctx := c.Context()` inside the handler and pass `ctx` to async work.
middleware/timeout/timeout_test.go (1)

71-77: Deflake timing assertion

150ms margin on a 100ms timeout can be flaky under CI load and with t.Parallel. Bump headroom or drop Parallel for this test.

-	require.Less(t, elapsed, 150*time.Millisecond, "context did not cancel within timeout")
+	require.Less(t, elapsed, 250*time.Millisecond, "context did not cancel within timeout")

Alternatively, remove t.Parallel() for this case.

docs/api/ctx.md (3)

45-52: Tighten wording; add explicit async guidance

  • Fix spelling (“cancellation”).
  • Explicitly state Ctx is recycled; do not use it after handler; call Context() inside handler.
-`Context` implements `context.Context`. However due to [current limitations in how fasthttp](...) works, `Deadline()`, `Done()` and `Err()` operate as a nop. The `fiber.Ctx` instance is reused after the handler returns and must not be used for asynchronous operations once the handler has completed. Call [`Context()`](#context-1) within the handler to obtain a `context.Context` that can be used outside the handler.
+`Context` implements `context.Context`. However, due to [current fasthttp limitations](...), `Deadline()`, `Done()` and `Err()` are no-ops.
+Important: `fiber.Ctx` is recycled. Do not use it for asynchronous work after the handler returns.
+Call [`Context()`](#context-1) inside the handler to obtain a `context.Context` you can safely use outside the handler.

76-111: Document panic-on-after-return and improve examples

  • Note that Context() panics if called after handler return.
  • Use a typed key in SetContext example to follow context best practices.
-Returns a `context.Context` that was previously set with [`SetContext`](#setcontext).
-If no context was set, it returns `context.Background()`. Unlike `fiber.Ctx` itself,
-the returned context is safe to use after the handler completes.
+Returns the per-request `context.Context` previously set with [`SetContext`](#setcontext).
+If none was set, returns `context.Background()`. Unlike `fiber.Ctx` itself, the returned
+context is safe to use after the handler completes.
+Panics if `Context()` is invoked after the handler has returned.

 ...
-app.Get("/", func(c fiber.Ctx) error {
-  c.SetContext(context.WithValue(context.Background(), "user", "alice"))
+type userKey struct{}
+app.Get("/", func(c fiber.Ctx) error {
+  base := context.WithValue(context.Background(), userKey{}, "alice")
+  c.SetContext(base)
   ctx := c.Context()
   go doWork(ctx)
   return nil
 })

333-339: Reword RequestCtx description

*fasthttp.RequestCtx is not a context.Context; avoid implying compatibility.

-Returns *fasthttp.RequestCtx that is compatible with the `context.Context` interface that requires a deadline, a cancellation signal, and other values across API boundaries.
+Returns the underlying *fasthttp.RequestCtx.
docs/guide/context.md (2)

58-68: Small copy edit for clarity and consistency

Use method parentheses and “retrieving” instead of “requesting.”

Apply this diff:

-You can customize the base context by calling `c.SetContext` before
-requesting it:
+You can customize the base context by calling `c.SetContext()` before
+retrieving it:

228-230: Reinforce the “call inside handler” requirement in Summary

Tie the safety note back in the Summary to reduce foot-guns.

Apply this diff:

-- Use `c.Context()` to obtain a `context.Context` that can outlive the handler,
-  and `c.SetContext()` to customize it with additional values or deadlines.
+- Use `c.Context()` to obtain a `context.Context` that can outlive the handler
+  (call it inside the handler; calling it after the handler returns will panic),
+  and `c.SetContext()` to customize it with additional values or deadlines.
ctx_test.go (2)

2849-2869: Release acquired ctx and tighten the equality assertion (minor)

  • Avoid leaking pooled ctx in tests by releasing it.
  • Optional: put expected first in require.Equal for clearer failure messages.

Apply this diff:

 func Test_Ctx_Context(t *testing.T) {
 	t.Parallel()
 	app := New()
 	c := app.AcquireCtx(&fasthttp.RequestCtx{})
+	defer app.ReleaseCtx(c)
 
 	t.Run("Nil_Context", func(t *testing.T) {
 		t.Parallel()
 		ctx := c.Context()
-		require.Equal(t, ctx, context.Background())
+		require.Equal(t, context.Background(), ctx)
 	})

2902-2914: Release acquired ctx (minor)

Free pooled ctx in this test as well.

Apply this diff:

 func Test_Ctx_SetContext(t *testing.T) {
 	t.Parallel()
 	app := New()
 	c := app.AcquireCtx(&fasthttp.RequestCtx{})
+	defer app.ReleaseCtx(c)
 
 	testKey := struct{}{}
 	testValue := "Test Value"
 	ctx := context.WithValue(context.Background(), testKey, testValue) //nolint:staticcheck // not needed for tests
 	c.SetContext(ctx)
 	require.Equal(t, testValue, c.Context().Value(testKey))
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e878cd8 and cac80c1.

📒 Files selected for processing (8)
  • ctx.go (2 hunks)
  • ctx_interface_gen.go (2 hunks)
  • ctx_test.go (2 hunks)
  • docs/api/ctx.md (2 hunks)
  • docs/guide/context.md (3 hunks)
  • docs/whats_new.md (2 hunks)
  • middleware/timeout/timeout.go (2 hunks)
  • middleware/timeout/timeout_test.go (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/api/ctx.md
  • docs/whats_new.md
  • docs/guide/context.md
🧠 Learnings (6)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#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
PR: gofiber/fiber#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
PR: gofiber/fiber#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
  • docs/api/ctx.md
  • docs/whats_new.md
  • docs/guide/context.md
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
PR: gofiber/fiber#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
  • middleware/timeout/timeout_test.go
  • ctx_interface_gen.go
  • docs/api/ctx.md
  • docs/whats_new.md
  • docs/guide/context.md
📚 Learning: 2024-11-29T12:37:27.581Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: app_test.go:893-895
Timestamp: 2024-11-29T12:37:27.581Z
Learning: In the `Test_App_ShutdownWithContext` function in `app_test.go`, the `clientDone` channel is used to synchronize the client's request completion before proceeding, eliminating the need for additional `time.Sleep` calls.

Applied to files:

  • middleware/timeout/timeout_test.go
  • ctx_test.go
📚 Learning: 2024-10-12T10:01:44.206Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/middleware_test.go:190-191
Timestamp: 2024-10-12T10:01:44.206Z
Learning: When testing session `IdleTimeout` expiration, it's acceptable to use `time.Sleep` to simulate the passage of time in tests.

Applied to files:

  • middleware/timeout/timeout_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#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:

  • middleware/timeout/timeout_test.go
  • docs/guide/context.md
🧬 Code graph analysis (2)
middleware/timeout/timeout_test.go (2)
middleware/timeout/config.go (1)
  • Config (10-26)
constants.go (1)
  • StatusRequestTimeout (81-81)
ctx_test.go (3)
middleware/timeout/timeout.go (1)
  • New (14-45)
app.go (1)
  • New (515-628)
ctx_interface_gen.go (1)
  • Ctx (18-420)
🪛 LanguageTool
docs/api/ctx.md

[grammar] ~45-~45: There might be a mistake here.
Context: ...e handler to obtain a context.Context that can be used outside the handler. ```go...

(QB_NEW_EN)


[grammar] ~78-~78: There might be a mistake here.
Context: ...ly set with SetContext. If no context was set, it returns `conte...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...y Context(). Use this to propagate deadlines, cancelation signals...

(QB_NEW_EN)

docs/whats_new.md

[grammar] ~485-~485: There might be a mistake here.
Context: ...tthat can be used outside the handler. - **SetContext**: Sets the basecontext.Con...

(QB_NEW_EN)

docs/guide/context.md

[grammar] ~28-~28: There might be a mistake here.
Context: ...tain a context.Context that can safely be used after the handler returns. By de...

(QB_NEW_EN)


[grammar] ~58-~58: There might be a mistake here.
Context: ...context by calling c.SetContext before requesting it: ```go app.Get("/job", fu...

(QB_NEW_EN)

🔇 Additional comments (8)
middleware/timeout/timeout_test.go (3)

45-49: LGTM: use c.Context() to drive cancellation

Using c.Context() here correctly exercises the middleware-provided timeout context.


64-69: LGTM: switch to c.Context() under timeout

This aligns tests with the new API.


158-167: LGTM: custom OnTimeout path

Confirms custom handler path with context-driven cancel.

docs/guide/context.md (1)

44-56: Async example LGTM

Clear and correct guidance to capture c.Context() within the handler and use it in a goroutine. Nice.

middleware/timeout/timeout.go (2)

10-13: Docstring update reads well

Accurately describes that the middleware replaces the request context with a deadline-bound one exposed via c.Context(). Good.


27-33: Context wrapping and restoration LGTM

Correctly derives tCtx from ctx.Context(), sets it for the handler, and restores the parent with cancel() in a defer. This ensures resource cleanup and proper stacking with other middleware that might also call SetContext.

ctx_test.go (2)

2870-2885: Panic-after-handler test LGTM

Correctly asserts that accessing Locals after handler completion panics.


2886-2901: Panic on c.Context() after handler LGTM

Matches the documented/desired lifecycle constraint.

@gaby
Copy link
Member Author

gaby commented Aug 29, 2025

/gemini review

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 crucial fix for context.Context support in Fiber, allowing for safe use of contexts in asynchronous operations. The new Context() and SetContext() helpers, along with proper context recycling, address a long-standing issue. The changes are well-implemented, with thorough tests and clear documentation updates. The refactoring of the timeout middleware to use these new helpers is a great showcase of their utility. My review includes a few minor suggestions to improve the new tests by ensuring resource cleanup and removing redundant code.

@ReneWerner87
Copy link
Member

old PR #3382

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 62e429c Previous: e83a762 Ratio
Benchmark_Compress_Levels_Parallel/Brotli_LevelBestCompression - B/op 1 B/op 0 B/op +∞

This comment was automatically generated by workflow using github-action-benchmark.

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: 0

♻️ Duplicate comments (1)
middleware/timeout/timeout.go (1)

37-43: Double-callback fixed: OnTimeout invoked only once on deadline paths

The outer check now triggers only when err == nil, preventing a second OnTimeout after runHandler handled a timeout error.

🧹 Nitpick comments (2)
middleware/timeout/timeout.go (2)

10-13: Doc wording drifts from behavior—clarify when ErrRequestTimeout is returned

As implemented, ErrRequestTimeout is returned when the handler returns a deadline/custom timeout error, or when the handler returns nil but the deadline elapsed. If the handler returns a non-timeout error while the deadline also elapsed, that handler error is propagated. Reflect this to avoid confusion.

-// New enforces a timeout for each incoming request. It replaces the request's
-// context with one that has the configured deadline, which is exposed through
-// c.Context(). If the timeout expires or any of the specified errors occur,
-// fiber.ErrRequestTimeout is returned.
+// New enforces a timeout for each incoming request by replacing the request's
+// context with a deadline-bound context, exposed via c.Context() for the duration
+// of handler execution. If the handler returns context.DeadlineExceeded (or one
+// of cfg.Errors), OnTimeout is invoked (if set) and fiber.ErrRequestTimeout is
+// returned. If the handler returns nil but the deadline elapsed, OnTimeout is
+// also invoked and fiber.ErrRequestTimeout is returned. Otherwise, the handler's
+// error (if any) is propagated.

37-37: Nit: compare tCtx.Err() directly to the sentinel

tCtx.Err() returns a sentinel; direct equality is simpler and marginally faster than errors.Is here.

-        if errors.Is(tCtx.Err(), context.DeadlineExceeded) && err == nil {
+        if tCtx.Err() == context.DeadlineExceeded && err == nil {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6e8a96d and 62e429c.

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

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Format Go code using gofumpt (enforced via make format)
Ensure code passes golangci-lint checks (enforced via make lint)
Optimize struct field alignment using betteralign (enforced via make betteralign)
Modernize Go code using gopls modernize (enforced via make modernize)

Files:

  • middleware/timeout/timeout.go
🧠 Learnings (1)
📓 Common learnings
Learnt from: gaby
PR: gofiber/fiber#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
PR: gofiber/fiber#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`.
⏰ 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: repeated
  • GitHub Check: Compare
🔇 Additional comments (2)
middleware/timeout/timeout.go (2)

53-55: Propagating non-nil OnTimeout error is correct

Good: allows custom OnTimeout to override the default 408 with a specific error/response.


27-33: Verified: no legacy fasthttp Context() calls remain
All c.Context() invocations only use the stdlib context.Context API (e.g. .Value), and all fasthttp access now goes through c.RequestCtx(). No further changes required.

@ReneWerner87 ReneWerner87 merged commit 2555a4f into main Sep 2, 2025
14 of 15 checks passed
@ReneWerner87 ReneWerner87 deleted the document-context.context-limitations-and-add-support branch September 2, 2025 12:05
@github-project-automation github-project-automation bot moved this from In Progress to Done in v3 Sep 2, 2025
Abhirup-99 pushed a commit to Abhirup-99/fiber that referenced this pull request Nov 3, 2025
@coderabbitai coderabbitai bot mentioned this pull request Dec 17, 2025
15 tasks
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]: Panic when using fiber.Ctx as context.Context after upgrading v3 beta.4 → v3.0.0-rc.1

3 participants