Skip to content

Conversation

ReneWerner87
Copy link
Member

Summary

  • delay 404 error creation in router to avoid unnecessary html escaping
  • centralize 404 construction to remove duplicate code

Testing

  • make audit (fails: lock by value in generated middleware files)
  • make generate
  • make betteralign
  • make modernize
  • make format
  • make test (fails: Test_Static_Compress/zstd_compression, Test_Static_Compress/br_compression i/o timeout)

https://chatgpt.com/codex/tasks/task_e_689ca563225c8326a9677a7887cfdb07

@Copilot Copilot AI review requested due to automatic review settings August 13, 2025 15:47
@ReneWerner87 ReneWerner87 requested a review from a team as a code owner August 13, 2025 15:47
Copy link
Contributor

coderabbitai bot commented Aug 13, 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

Replaced ad-hoc 404 message construction and the html import in router.go with direct ErrNotFound / ErrMethodNotAllowed returns, simplified next/nextCustom control flow, and updated tests/docs to expect "Not Found" (plus a benchmark allocation report added).

Changes

Cohort / File(s) Summary
Router control-flow & error handling
router.go
Removed html import and ad-hoc "Cannot " construction; return ErrNotFound / ErrMethodNotAllowed directly; removed intermediate var err error and simplified next / nextCustom control flow.
Tests — router & benchmark
router_test.go
Updated 404 expectations from "Cannot ..." to "Not Found"; added b.ReportAllocs() to Benchmark_Router_NotFound.
Tests — client & middleware & hooks
client/core_test.go, middleware/keyauth/keyauth_test.go, middleware/logger/logger_test.go, middleware/static/static_test.go, hooks_test.go
Import ordering/formatting tweaks; updated multiple test assertions/log expectations to expect "Not Found" for 404 cases; some tests changed listen ports to :0; no production API changes.
Documentation
docs/guide/routing.md
Replaced sample 404 outputs from "Cannot GET /..." to "Not Found"; removed trailing whitespace in a Params example.

Sequence Diagram(s)

sequenceDiagram
  participant C as Client
  participant R as Router
  participant H as Handler

  C->>R: Request(method, path)
  alt route and method match
    R->>H: Invoke handler
    H-->>R: Handler response
    R-->>C: 200 (handler response)
  else route exists but method mismatch
    R-->>C: ErrMethodNotAllowed (405)
  else no matching route
    R-->>C: ErrNotFound (404)
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Suggested labels

🧹 Updates, v3

Suggested reviewers

  • gaby
  • sixcolors
  • efectn

Poem

I nibble old strings and tidy the road,
404s now short and neatly showed.
Methods checked, the paths made right,
Tests updated, benchmarks light.
A rabbit hops — the router's bright. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/2025-08-13-15-47-17

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

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.

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 refactors the routing error handling by delaying the creation of 404 "Not Found" errors and centralizing their construction. This change aims to prevent unnecessary HTML escaping of paths and reduce code duplication within the router's "next" and "nextCustom" methods.

Highlights

  • Optimized 404 Error Generation: The creation of the 404 "Not Found" error object is now deferred until it's actually needed, preventing premature and potentially redundant HTML escaping of the request path.
  • Consolidated Error Construction: A new helper function, "cannotRouteError", has been introduced to centralize the logic for generating 404 errors, thereby eliminating duplicate code across different routing paths.
  • Streamlined Router Logic: The "next" and "nextCustom" functions within the router have been updated to utilize a local "notFound" closure, which leverages the new "cannotRouteError" function, simplifying error return statements.
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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

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

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 effectively centralizes the creation of 404 errors into a new cannotRouteError helper function and delays its creation to avoid unnecessary work in the routing logic. This is a solid improvement for both code clarity and performance. My review includes a suggestion to further optimize the implementation by removing the intermediate notFound closure in the next and nextCustom functions to avoid allocations in these performance-critical paths.

Copy link

codecov bot commented Aug 13, 2025

Codecov Report

❌ Patch coverage is 83.33333% with 1 line in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@8f2c4e2). Learn more about missing BASE report.
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
router.go 83.33% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3683   +/-   ##
=======================================
  Coverage        ?   91.98%           
=======================================
  Files           ?      114           
  Lines           ?    11484           
  Branches        ?        0           
=======================================
  Hits            ?    10564           
  Misses          ?      661           
  Partials        ?      259           
Flag Coverage Δ
unittests 91.98% <83.33%> (?)

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

@Copilot 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 pull request optimizes error handling in the router by deferring 404 error creation until it's actually needed. The changes centralize 404 error construction to eliminate code duplication and avoid unnecessary HTML escaping operations when the error might not be used.

Key changes:

  • Introduced a shared cannotRouteError function to centralize 404 error creation
  • Replaced immediate error creation with lazy evaluation using closure functions
  • Removed duplicate error handling code between next and nextCustom methods

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

🧹 Nitpick comments (3)
router.go (3)

161-166: Avoid per-request closure allocation; inline lazy 404 creation

The notFound closure is instantiated on every request, even when not used (e.g., 405 cases). Inline the call to cannotRouteError at the return sites to keep the “delay” semantics without closure overhead and capture.

Apply this diff:

-    // Moved from app.handler because middleware may break the route chain
-    notFound := func() error {
-        return cannotRouteError(c.Method(), c.getPathOriginal())
-    }
     if c.matched {
-        return false, notFound()
+        return false, cannotRouteError(c.Method(), c.getPathOriginal())
     }

208-211: Inline final 404 creation to remove dependency on local closure

Consistent with removing the closure above, inline the 404 error creation here as well.

-    return false, notFound()
+    return false, cannotRouteError(c.Method(), c.getPathOriginal())

306-309: Inline the final 404 in nextCustom for consistency and performance

Replace the last notFound() call with direct construction.

-    return false, notFound()
+    return false, cannotRouteError(c.Method(), c.getPathOriginal())
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87b6e53 and b221e07.

📒 Files selected for processing (1)
  • router.go (5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
router.go (2)
app.go (1)
  • NewError (894-903)
constants.go (2)
  • StatusNotFound (77-77)
  • ErrMethodNotAllowed (123-123)
⏰ 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). (5)
  • GitHub Check: unit (1.24.x, macos-latest)
  • GitHub Check: Compare
  • GitHub Check: unit (1.24.x, windows-latest)
  • GitHub Check: unit (1.24.x, macos-13)
  • GitHub Check: repeated
🔇 Additional comments (2)
router.go (2)

109-112: Consolidated 404 error construction with proper HTML-escaping — good change

Centralizing 404 creation via cannotRouteError improves consistency, removes duplication, and ensures HTML-escaping is applied only when the error is actually produced.


259-264: Inline error construction in router.go to avoid closure allocation

CustomCtx already exposes both getPathOriginal() and Method() via the embedded Ctx, so it’s safe to remove the extra closure.

• Remove the notFound closure (and its comment) around line 259 in router.go.
• Inline the cannotRouteError call directly in the return.

Apply this diff:

--- a/router.go
+++ b/router.go
@@ -259,8 +259,6 @@
-    // Moved from app.handler because middleware may break the route chain
-    notFound := func() error {
-        return cannotRouteError(c.Method(), c.getPathOriginal())
-    }
     if c.getMatched() {
-        return false, notFound()
+        return false, cannotRouteError(c.Method(), c.getPathOriginal())
     }

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

🧹 Nitpick comments (5)
utils/escape_path.go (3)

12-27: Confirm encoding semantics: spaces become '+' and '%' is re-encoded

EscapePath uses fasthttp.AppendQuotedArg per segment, which applies query-arg style escaping: spaces are encoded as '+' and any literal '%' is encoded to '%25'. For path segments per RFC 3986, spaces are typically encoded as '%20' and existing percent-encodings are usually preserved. Since this is used for error message display only, this might be acceptable, but please confirm this behavior is intentional to avoid surprises if callers reuse it for URL construction.

If the '+' behavior is intended, consider clarifying it in the doc comment to prevent misuse.

Apply this doc update to set expectations:

-// EscapePath returns a URL-escaped path while preserving slashes.
-// It pre-allocates extra capacity to minimize allocations.
+// EscapePath returns a URL-escaped path while preserving slashes.
+// Each segment is escaped via fasthttp.AppendQuotedArg:
+//   - spaces become '+'
+//   - literal '%' becomes '%25' (existing percent-encodings are re-encoded)
+// This helper is intended for safe display (e.g., error messages), not for generating canonical URLs.
+// It pre-allocates extra capacity to minimize allocations.
 func EscapePath(path string) string {

16-16: Avoid potential reallocations in worst-case (non-ASCII-heavy inputs)

Preallocating len+len/2 may still trigger reallocations when most bytes need escaping (e.g., non-ASCII, which grow to ~3x). Consider reserving up to 3x to minimize reallocations in worst cases. This is a micro-optimization and optional.

-	buf := make([]byte, 0, len(b)+len(b)/2)
+	// In the worst case, every byte expands to 3 bytes ("%XX").
+	// Pre-allocate up to 3x to reduce reallocations on non-ASCII-heavy inputs.
+	buf := make([]byte, 0, len(b)*3)

14-17: Optional guard for empty path inputs

If an empty path ever reaches this function, it currently returns an empty string. For better UX in error messages, returning "/" might be preferable. Only apply if consistent with upstream behavior of getPathOriginal.

 func EscapePath(path string) string {
+	if path == "" {
+		return "/"
+	}
 	b := gutils.UnsafeBytes(path)
utils/escape_path_test.go (1)

5-17: Optional: add trailing-slash and multi-slash cases

Since EscapePath preserves slashes and encodes segments only, it’s useful to lock that in with tests like "/users/" and "///". Not required for this PR but helps prevent regressions.

Here are example additions you could append to cases:

"/users/": "/users/",
"///":     "///",
router.go (1)

204-208: Method-not-allowed path: ensure Allow header uniqueness (optional)

When multiple routes across methods match, Allow may accumulate duplicates. Rare in practice due to deduping and route structure, but consider de-duplicating before returning 405 for spec cleanliness.

You could track seen methods in a small bool array keyed by index to avoid duplicates before appending.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b221e07 and 81b076c.

📒 Files selected for processing (4)
  • router.go (13 hunks)
  • router_test.go (1 hunks)
  • utils/escape_path.go (1 hunks)
  • utils/escape_path_test.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
utils/escape_path_test.go (1)
utils/escape_path.go (1)
  • EscapePath (14-27)
router.go (1)
utils/escape_path.go (1)
  • EscapePath (14-27)
🪛 GitHub Check: lint
utils/escape_path_test.go

[failure] 3-3:
should only use grouped 'import' declarations (grouper)

🪛 GitHub Actions: golangci-lint
utils/escape_path_test.go

[error] 3-3: should only use grouped 'import' declarations (grouper)

⏰ 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 (12)
router_test.go (2)

415-417: LGTM: 404 body now percent-encodes the injected content

Assertion updated to expect a percent-encoded path in the 404 body, matching the new centralized escaping. This closes the HTML-escaping gap and is safer for plain-text responses.


419-423: LGTM: cannotRouteError escaping is covered

Great addition. This directly validates that cannotRouteError uses EscapePath for percent-encoding.

router.go (10)

13-16: LGTM: import split clarifies responsibilities

Using fiber/v3/utils for EscapePath and aliasing github.com/gofiber/utils/v2 as gutils avoids naming collisions and improves readability.


109-111: Centralized 404 creation improves consistency and reduces duplication

cannotRouteError standardizes NotFound construction and defers escaping to utils.EscapePath. This avoids scattered HTML-escaping and makes the path handling uniform.


137-139: LGTM: zero-copy string conversion during matching

Using gutils.UnsafeString on detectionPath and path here avoids allocations during hot path matching.


161-164: LGTM: return standardized 404 when a route matched earlier but yielded no handler chain

Returning cannotRouteError here keeps behavior consistent with requestHandler’s default error handling.


193-194: LGTM: consistent matching in alternate-method scan

The same zero-copy matching logic is applied when scanning other methods, maintaining performance characteristics.


351-357: LGTM: gutils for case/trailing-slash normalization

Switch to gutils.ToLower/TrimRight aligns with the rest of the refactor and reduces bespoke utility usage.


396-401: LGTM: normalizePath refactor mirrors register logic

Normalization is consistent across register/remove flows, reducing edge-case drift.


446-447: LGTM: uppercase methods via gutils.ToUpper

Keeps method normalization consistent and avoids ad-hoc case handling.


497-501: LGTM: registration normalization with gutils

Using gutils.ToLower/TrimRight in register mirrors normalizePath, ensuring pairwise consistency.


509-510: LGTM: method normalization at registration

Uppercasing here prevents surprises when mixing casing in API usage.

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

🧹 Nitpick comments (3)
helpers.go (2)

141-157: Clarify escaping semantics (+ for spaces) and verify double-encoding is desired

escapePath uses fasthttp.AppendQuotedArg per segment, which encodes spaces as '+' and percent-encodes other bytes. For paths, '+' isn’t the standard representation of spaces (usually %20), but if the intent is “display-only” for 404 messages and to avoid HTML escaping, this is fine. However, please clarify this in the docstring and confirm that double-encoding existing '%' sequences (e.g., "/a%2Fb" -> "/a%252Fb") is intended.

Apply this diff to improve the comment:

-// escapePath returns a URL-escaped path while preserving slashes.
-// It pre-allocates extra capacity to minimize allocations.
+// escapePath returns a URL-escaped path while preserving '/' separators.
+// Note: spaces are encoded as '+' (fasthttp.AppendQuotedArg semantics), and all
+// non-ASCII or reserved bytes are percent-encoded. Existing '%' bytes will be
+// encoded (i.e., already-escaped sequences are not decoded or preserved).
+// It pre-allocates extra capacity to minimize allocations.

141-157: Optional: Add a fast path to avoid allocation when no escaping is needed

Right now we always allocate and re-encode even for safe ASCII paths like "/foo/bar". Since this runs on 404s, a trivial pre-check could allow returning the original string unchanged and avoid one allocation/copy in the common case.

If desired, I can propose a minimal “needs-escape” pre-scan consistent with fasthttp’s rules (ALPHA / DIGIT / '-' / '.' / '_' / '~' and '/').

helpers_test.go (1)

484-498: Benchmark representative inputs (+, UTF-8, pre-escaped) to catch regressions

Adding a couple more samples makes the benchmark more representative and will flag regressions in cases we explicitly support in tests.

 func Benchmark_EscapePath(b *testing.B) {
   samples := []string{
     "/foo/bar",
     "/does/not/exist<script>alert('foo');</script>",
+    "/foo+bar",
+    "/créer",
+    "/a%2Fb",
   }
   for _, sample := range samples {
     b.Run(sample, func(b *testing.B) {
       b.ReportAllocs()
       for b.Loop() {
         _ = escapePath(sample)
       }
     })
   }
 }
📜 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 settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 81b076c and e66b0a3.

📒 Files selected for processing (3)
  • helpers.go (1 hunks)
  • helpers_test.go (1 hunks)
  • router.go (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • router.go
⏰ 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: Compare
  • GitHub Check: repeated

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

🧹 Nitpick comments (2)
router_test.go (1)

914-914: Good addition: allocation reporting for the NotFound benchmark

Adding b.ReportAllocs() here is useful to observe heap activity for 404 paths.

Consider also resetting the timer to exclude setup costs from benchmark timing.

 func Benchmark_Router_NotFound(b *testing.B) {
-	b.ReportAllocs()
+	b.ReportAllocs()
+	b.ResetTimer()
router.go (1)

300-303: CustomCtx 405 vs 404 split is clean

Method-not-allowed returns the shared sentinel error; not-found goes through the sanitizer. Looks good.

There’s test coverage for DefaultCtx 404 escaping. Consider adding a parallel CustomCtx test asserting the escaped message to guard against regressions in the custom path. I can draft it if helpful.

📜 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 settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e66b0a3 and 7fa0bfa.

📒 Files selected for processing (2)
  • router.go (5 hunks)
  • router_test.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
router.go (2)
app.go (1)
  • NewError (894-903)
constants.go (2)
  • StatusNotFound (77-77)
  • ErrMethodNotAllowed (123-123)
⏰ 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). (5)
  • GitHub Check: unit (1.25.x, macos-13)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: repeated
  • GitHub Check: Compare
🔇 Additional comments (4)
router.go (4)

162-163: 404 path now created lazily with centralized helper

Returning cannotRouteError only when needed avoids unnecessary HTML escaping on hot paths. Nice cleanup.


205-206: 405 handling remains explicit and fast

Early return of ErrMethodNotAllowed is clear and avoids formatting/escaping work. Header population happens just above this, as before.


207-208: Final not-found fallback uses centralized helper

Consistent with the earlier branch; keeps all 404 strings sanitized and uniform.


257-258: CustomCtx path: same 404 behavior via helper

Parity with the DefaultCtx path is preserved; escaping is handled identically.

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

🔭 Outside diff range comments (1)
router.go (1)

160-203: Avoid mutating ctx.indexRoute on 405 path; (optional) consider advertising HEAD when GET is allowed

Short: mutating c.indexRoute/c.setIndexRoute while building an Allow header for a 405 is unnecessary and pollutes ctx state. Remove that mutation in both next() and nextCustom(). Optionally, you can append HEAD when GET is present (this is a behavior change — update tests if you adopt it).

Files to change:

  • router.go — DefaultCtx next() (removes c.indexRoute assignment while scanning other methods; optionally add HEAD) — currently c.indexRoute = indexRoute (router.go:197)
  • router.go — nextCustom() (same change for CustomCtx) — currently c.setIndexRoute(indexRoute) (router.go:292)

Apply the following (showing both places). The HEAD-related code is optional; keep it out if you want to avoid changing existing Allow header behavior and test expectations.

@@
-    exists := false
-    methods := app.config.RequestMethods
+    exists := false
+    methods := app.config.RequestMethods
+    // Track GET/HEAD to optionally include HEAD when GET is allowed.
+    foundGet, foundHead := false, false
@@
-            if route.match(utils.UnsafeString(c.detectionPath), utils.UnsafeString(c.path), &c.values) {
-                // We matched
-                exists = true
-                // Add method to Allow header
-                c.Append(HeaderAllow, methods[i])
-                // Break stack loop
-                break
-            }
+            if route.match(utils.UnsafeString(c.detectionPath), utils.UnsafeString(c.path), &c.values) {
+                // We matched
+                exists = true
+                m := methods[i]
+                if m == "GET" {
+                    foundGet = true
+                }
+                if m == "HEAD" {
+                    foundHead = true
+                }
+                // Add method to Allow header
+                c.Append(HeaderAllow, m)
+                // Break stack loop
+                break
+            }
@@
-        c.indexRoute = indexRoute
+        // Do not persist indexRoute while only collecting Allow header values for a 405.
     }
-    if exists {
-        return false, ErrMethodNotAllowed
-    }
+    if exists {
+        // Optional: advertise HEAD when GET is allowed (common server behavior).
+        if foundGet && !foundHead {
+            c.Append(HeaderAllow, "HEAD")
+        }
+        return false, ErrMethodNotAllowed
+    }
     return false, ErrNotFound
 }

And mirror the same edits in nextCustom():

@@
-    exists := false
-    methods := app.config.RequestMethods
+    exists := false
+    methods := app.config.RequestMethods
+    foundGet, foundHead := false, false
@@
-            if route.match(c.getDetectionPath(), c.Path(), c.getValues()) {
-                // We matched
-                exists = true
-                // Add method to Allow header
-                c.Append(HeaderAllow, methods[i])
-                // Break stack loop
-                break
-            }
+            if route.match(c.getDetectionPath(), c.Path(), c.getValues()) {
+                // We matched
+                exists = true
+                m := methods[i]
+                if m == "GET" {
+                    foundGet = true
+                }
+                if m == "HEAD" {
+                    foundHead = true
+                }
+                // Add method to Allow header
+                c.Append(HeaderAllow, m)
+                // Break stack loop
+                break
+            }
@@
-        c.setIndexRoute(indexRoute)
+        // Do not persist indexRoute while only collecting Allow header values for a 405.
     }
-    if exists {
-        return false, ErrMethodNotAllowed
-    }
+    if exists {
+        if foundGet && !foundHead {
+            c.Append(HeaderAllow, "HEAD")
+        }
+        return false, ErrMethodNotAllowed
+    }
     return false, ErrNotFound
 }

Tests to consider:

  • Changing Allow to auto-include HEAD will alter existing assertions (e.g. app_test.go Test_App_MethodNotAllowed expects "POST, OPTIONS" or "GET, POST, OPTIONS" depending on registration). If you adopt HEAD auto-inclusion, update those expectations.
  • To find all places asserting Allow headers: run a repo search such as:
    rg -n -A3 -B3 'Allow' --type go

Recommendation:

  • I suggest applying the index mutation removal in both next() and nextCustom() now (safe, reduces ctx state pollution).
  • Keep the HEAD auto-addition as an opt-in change — only enable if you want to change public behavior and update tests accordingly.
🧹 Nitpick comments (1)
router.go (1)

255-298: Mirror the 405 refinements in nextCustom; consider factoring shared logic

  • Same two tweaks as in next: don’t mutate c.setIndexRoute on an error path; optionally include HEAD in Allow when GET is allowed.
  • Consider extracting the “scan other methods and build Allow” logic into a small helper to keep next and nextCustom from drifting.

Apply this diff to align behavior and remove the unnecessary state mutation:

@@
- exists := false
- methods := app.config.RequestMethods
+ exists := false
+ methods := app.config.RequestMethods
+ // Track GET/HEAD to optionally include HEAD when GET is allowed.
+ foundGet, foundHead := false, false
@@
-            if route.match(c.getDetectionPath(), c.Path(), c.getValues()) {
+            if route.match(c.getDetectionPath(), c.Path(), c.getValues()) {
                 // We matched
                 exists = true
                 // Add method to Allow header
-                c.Append(HeaderAllow, methods[i])
+                m := methods[i]
+                if m == "GET" {
+                    foundGet = true
+                }
+                if m == "HEAD" {
+                    foundHead = true
+                }
+                c.Append(HeaderAllow, m)
                 // Break stack loop
                 break
             }
         }
-        c.setIndexRoute(indexRoute)
+        // No need to persist indexRoute when returning an error afterwards.
     }
-    if exists {
-        return false, ErrMethodNotAllowed
-    }
+    if exists {
+        // Optionally advertise HEAD when GET is allowed (common server behavior).
+        if foundGet && !foundHead {
+            c.Append(HeaderAllow, "HEAD")
+        }
+        return false, ErrMethodNotAllowed
+    }
     return false, ErrNotFound

If you prefer a helper to avoid duplication:

  • Extract a method like app.buildAllowHeaderAndDecide(cCtx, methodInt, treeHash) that returns (exists bool).
  • Use an interface satisfied by both DefaultCtx and CustomCtx for the minimal calls used here (Append, Path getters, etc.).
📜 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 settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7fa0bfa and d1d0959.

📒 Files selected for processing (2)
  • router.go (4 hunks)
  • router_test.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • router_test.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
router.go (1)
constants.go (2)
  • ErrNotFound (122-122)
  • ErrMethodNotAllowed (123-123)
⏰ 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)
router.go (2)

156-158: LGTM: using sentinel ErrNotFound avoids per-request formatting and allocations

Returning ErrNotFound here keeps the hot path lean and defers response construction to the centralized error handler. Matches the PR goal of delaying 404 creation.


251-253: LGTM: consistent 404 sentinel usage in CustomCtx path

Mirrors the DefaultCtx code path and preserves behavior while avoiding unnecessary string work.

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

🧹 Nitpick comments (3)
docs/guide/routing.md (2)

42-47: Nit: Capitalize “Express.js”.

Minor editorial fix to keep brand naming consistent and professional.

-As with the expressJs framework, the order of the route declaration plays a role.
+As with the Express.js framework, the order of the route declaration plays a role.

229-232: Clarify escaping note for datetime constraints (optional).

Consider explicitly listing that 404s will use the uniform “Not Found” body when constraints fail to match, which ties back to the new behavior.

middleware/static/static_test.go (1)

965-972: Fix mismatched assertion message in else-branch (minor).

The assertion checks for “Are you a hacker?” but the failure message still mentions “Not Found”. Update the message for clarity.

-        // If we got a 404, we expect the "Not Found" message because that's how fiber handles NotFound by default.
+        // If we got a 404, we expect the "Not Found" message because that's how Fiber handles NotFound by default.
         if status == 404 {
             require.Contains(t, string(body), "Not Found",
                 "Blocked traversal should have a \"Not Found\" message for %s", path)
         } else {
-            require.Contains(t, string(body), "Are you a hacker?",
-                "Blocked traversal should have a \"Not Found\" message for %s", path)
+            require.Contains(t, string(body), "Are you a hacker?",
+                "Blocked traversal should have an \"Are you a hacker?\" message for %s", path)
         }
📜 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 settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d1d0959 and 5ecc8aa.

📒 Files selected for processing (6)
  • client/core_test.go (3 hunks)
  • docs/guide/routing.md (5 hunks)
  • middleware/keyauth/keyauth_test.go (2 hunks)
  • middleware/logger/logger_test.go (3 hunks)
  • middleware/static/static_test.go (4 hunks)
  • router_test.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • router_test.go
🧰 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/guide/routing.md
🧠 Learnings (4)
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/keyauth/keyauth_test.go
  • middleware/logger/logger_test.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#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:

  • middleware/static/static_test.go
  • client/core_test.go
📚 Learning: 2024-12-15T19:56:45.935Z
Learnt from: ckoch786
PR: gofiber/fiber#3230
File: docs/whats_new.md:944-951
Timestamp: 2024-12-15T19:56:45.935Z
Learning: Detailed usage examples and explanations for new methods like `RemoveRoute` and `RemoveRouteByName` are documented in `docs/api/app.md`, so it's unnecessary to duplicate them in `docs/whats_new.md`.

Applied to files:

  • docs/guide/routing.md
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/logger/logger_test.go
⏰ 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). (5)
  • GitHub Check: Compare
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: unit (1.25.x, macos-13)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: repeated
🔇 Additional comments (12)
docs/guide/routing.md (2)

183-184: Docs correctly reflect the new 404 body (“Not Found”).

All updated examples now align with the centralized 404 handling. Good consistency across constraints and regex examples.

Also applies to: 197-201, 216-221, 246-247


1-356: No "Cannot GET" occurrences found — resolving

Searched docs/** (case-sensitive) and the repo (case-insensitive) for "Cannot GET" using ripgrep; no matches were found. No further action required.

middleware/logger/logger_test.go (3)

24-28: Import reflow is fine.

No functional impact; grouping is clean.


468-474: Update to “Not Found” matches new router behavior.

Expected line content reflects centralized 404 handling. Looks good.


1039-1045: Colorized “Not Found” expectation aligns with new default message.

Assertion matches the ForceColors/DisableColors test setup.

client/core_test.go (2)

13-15: Import order tweak is fine.

No runtime effect.


170-173: “Not Found” expected body is correct.

These subtests now align with the standardized 404 response body.

Also applies to: 186-190

middleware/keyauth/keyauth_test.go (2)

12-15: Import reordering looks fine.

No behavioral change.


122-126: Param-source empty key case updated to “Not Found” is correct.

When the token is part of the path and missing, the router never reaches the handler; 404 body is now standardized.

middleware/static/static_test.go (3)

60-63: 404 body assertion updated to “Not Found” is correct.

This matches the framework’s standardized 404 body.


179-182: “Not Found” expectation after deletion is correct.

Consistent with updated NotFound handler behavior.


774-809: Address flakiness/timeouts in compression subtests — verification incomplete

Tried to verify by running the test in the sandbox. rg found the test (middleware/static/static_test.go:774), but go test failed here due to module/environment limits ("go: cannot find main module" + telemetry sidecar warning). I couldn't run the tests to confirm flakiness or timeout improvements.

What I inspected

  • File: middleware/static/static_test.go — Test_Static_Compress (lines ~774-809) — subtests call t.Parallel() and use the same app/FS instance.

Suggested fixes (choose one)

Option A — run subtests sequentially (simplest)

 for _, algo := range algorithms {
     t.Run(algo+"_compression", func(t *testing.T) {
-        t.Parallel()
         // request non-compressible file (less than 200 bytes), Content Length will remain the same

Option B — isolate state per subtest (each subtest gets its own app/FS)

 for _, algo := range algorithms {
     t.Run(algo+"_compression", func(t *testing.T) {
-        t.Parallel()
-        // request non-compressible file (less than 200 bytes), Content Length will remain the same
+        // Dedicated app per subtest to avoid concurrent compression of the same files.
+        app := fiber.New()
+        app.Get("/*", New(dir, Config{ Compress: true }))
+
+        // request non-compressible file (less than 200 bytes), Content Length will remain the same

Also consider increasing testConfig.Timeout for compression tests if CI remains near the 10s limit.

Please verify locally (run from the repository root where go.mod is present):

rg -n '^func Test_Static_Compress' middleware/static/static_test.go
go test ./middleware/static -run Test_Static_Compress -count=5 -timeout=120s -v

I cannot complete runtime verification in the sandbox due to the missing module; please run the commands above and report back if you want me to re-evaluate based on results.

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

💡 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 settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 06339a4 and c5deff8.

📒 Files selected for processing (2)
  • hooks_test.go (2 hunks)
  • middleware/keyauth/keyauth_test.go (3 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • middleware/keyauth/keyauth_test.go
  • hooks_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • middleware/keyauth/keyauth_test.go
  • hooks_test.go
📚 Learning: 2024-12-13T08:14:22.851Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: hooks_test.go:228-228
Timestamp: 2024-12-13T08:14:22.851Z
Learning: In Go test files, prefer using the `require` methods from the `testify` package for assertions instead of manual comparisons and calls to `t.Fatal` or `t.Fatalf`.

Applied to files:

  • middleware/keyauth/keyauth_test.go
  • hooks_test.go
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#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:

  • hooks_test.go
⏰ 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). (5)
  • GitHub Check: unit (1.25.x, macos-13)
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: repeated
  • GitHub Check: Compare
🔇 Additional comments (4)
hooks_test.go (1)

12-14: LGTM: import placement for log aligns with usage in this test

Import of github.com/gofiber/fiber/v3/log is correctly grouped and used later for capturing hook error logs.

middleware/keyauth/keyauth_test.go (3)

15-17: LGTM: import block reordering is fine

The reordering/groups are consistent; no functional impact.


169-173: No-op whitespace change

No issues.


194-197: Approve: update 404 expectation to "Not Found" for missing param token

Matches the centralized 404 behavior and the router change away from "Cannot GET /…".

  • middleware/keyauth/keyauth_test.go — lines 194–197 (expect 404 and "Not Found")
  • Repo search for "Cannot GET" returned no matches.

github-actions[bot]

This comment was marked as resolved.

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

🔭 Outside diff range comments (1)
hooks_test.go (1)

320-331: Avoid t usage in goroutine; assert in main goroutine for prefork case too

The same testing pattern applies here for prefork. This also helps standardize on testify/require in the main goroutine.

-	go func() {
-		time.Sleep(1000 * time.Millisecond)
-		assert.NoError(t, app.Shutdown())
-	}()
+	done := make(chan error, 1)
+	go func() {
+		time.Sleep(1 * time.Second)
+		done <- app.Shutdown()
+	}()
 
 	app.Hooks().OnFork(func(pid int) error {
 		require.Equal(t, 1, pid)
 		return nil
 	})
 
-	require.NoError(t, app.prefork(":0", nil, ListenConfig{DisableStartupMessage: true, EnablePrefork: true}))
+	require.NoError(t, app.prefork(":0", nil, ListenConfig{DisableStartupMessage: true, EnablePrefork: true}))
+	require.NoError(t, <-done)
♻️ Duplicate comments (2)
hooks_test.go (2)

281-286: Good move to :0; avoid using testing.T from a goroutine and prefer require in main goroutine

Nice fix switching to an ephemeral port (as previously suggested). To avoid racy writes to t from goroutines and to fail fast, capture Shutdown errors in a channel and assert in the main goroutine.

Apply this minimal refactor:

-	go func() {
-		time.Sleep(1000 * time.Millisecond)
-		assert.NoError(t, app.Shutdown())
-	}()
-	require.NoError(t, app.Listen(":0"))
+	done := make(chan error, 1)
+	go func() {
+		time.Sleep(1 * time.Second)
+		done <- app.Shutdown()
+	}()
+	require.NoError(t, app.Listen(":0"))
+	require.NoError(t, <-done)

304-311: Use channel handshake instead of asserting from a goroutine; keep :0

Same rationale as above: avoid calling assert/require on t in a goroutine; assert in the main goroutine and keep the ephemeral port.

-	go func() {
-		time.Sleep(1000 * time.Millisecond)
-		assert.NoError(t, app.Shutdown())
-	}()
-
-	require.NoError(t, app.Listen(":0", ListenConfig{DisableStartupMessage: true, EnablePrefork: true}))
+	done := make(chan error, 1)
+	go func() {
+		time.Sleep(1 * time.Second)
+		done <- app.Shutdown()
+	}()
+	require.NoError(t, app.Listen(":0", ListenConfig{DisableStartupMessage: true, EnablePrefork: true}))
+	require.NoError(t, <-done)
 	require.Equal(t, "ready", buf.String())
🧹 Nitpick comments (1)
hooks_test.go (1)

12-14: LGTM on importing fiber/log; minor test hygiene: restore logger output after redirection

The added log import is appropriate for capturing output in tests. However, tests that call log.SetOutput risk leaking global state across the suite. Consider restoring the original writer via t.Cleanup to avoid cross-test interference.

Example pattern:

// after creating your buffer
// import "os"
log.SetOutput(&buf)
t.Cleanup(func() { log.SetOutput(os.Stderr) })
📜 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 settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c5deff8 and 19711d0.

📒 Files selected for processing (1)
  • hooks_test.go (5 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
PR: gofiber/fiber#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:

  • hooks_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • hooks_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
PR: gofiber/fiber#2922
File: middleware/cors/utils.go:63-71
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The project uses the testify/assert package for assertions in unit tests.

Applied to files:

  • hooks_test.go
📚 Learning: 2024-12-13T08:14:22.851Z
Learnt from: efectn
PR: gofiber/fiber#3162
File: hooks_test.go:228-228
Timestamp: 2024-12-13T08:14:22.851Z
Learning: In Go test files, prefer using the `require` methods from the `testify` package for assertions instead of manual comparisons and calls to `t.Fatal` or `t.Fatalf`.

Applied to files:

  • hooks_test.go
📚 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:

  • hooks_test.go
🧬 Code Graph Analysis (1)
hooks_test.go (2)
listen.go (1)
  • ListenConfig (42-125)
hooks.go (1)
  • ListenData (38-42)
⏰ 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). (5)
  • GitHub Check: Compare
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: unit (1.25.x, macos-latest)
  • GitHub Check: repeated
  • GitHub Check: unit (1.25.x, macos-13)
🔇 Additional comments (1)
hooks_test.go (1)

422-424: LGTM: using Port "0" in ListenData for hook error path

Switching to port "0" removes privilege/port-collision concerns in this unit test while preserving semantics of the error-path check.

@gaby gaby changed the title chore: delay routing error creation 🧹 chore: delay routing error creation Aug 15, 2025
@gaby gaby merged commit 8f90f97 into main Aug 15, 2025
15 checks passed
@gaby gaby deleted the codex/2025-08-13-15-47-17 branch August 15, 2025 03:05
@github-project-automation github-project-automation bot moved this to Done in v3 Aug 15, 2025
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.

2 participants