Skip to content

Conversation

@Romakita
Copy link
Collaborator

@Romakita Romakita commented Nov 10, 2025

  • Introduced callNext utility for improved response handling in middleware.
  • Refined middleware handler to support async operations and detailed error handling.
  • Resolved minor issues with static handler registration.
  • Added comprehensive test for global middleware integration.

Summary by CodeRabbit

  • Refactor

    • Improved middleware execution to properly await async handlers and propagate errors to the next layer.
    • Enhanced response status handling so explicitly set statuses (including 404) are recognized.
  • Tests

    • Added end-to-end coverage for global middleware behavior.
    • Updated a test expectation to reflect current response status behavior.
  • Chores

    • Removed unused internal imports.
    • Relaxed Fastify test coverage threshold.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Walkthrough

Converts Fastify middleware wrapper to async and adds a helper to conditionally invoke next(); adds a global Fastify middleware test; removes unused DI imports; adjusts one test expectation and a vitest branch threshold; and adds explicit status tracking in Koa response with associated test change.

Changes

Cohort / File(s) Summary
Fastify middleware core
packages/platform/platform-fastify/src/components/PlatformFastify.ts
Imports PlatformContext, adds module-scoped callNext(next, metadata, $ctx) helper, and changes MIDDLEWARE mapHandler wrapper to async that awaits runInContext($ctx, () => handler($ctx)), calls callNext(done, metadata, $ctx), and returns the result. Minor whitespace tweak in mapLayers.
Global middleware test
packages/platform/platform-fastify/test/global-middleware.spec.ts
Adds test file with TestHealth controller and GlobalInputMiddleware; boots platform test environment, registers global middleware, and asserts GET /rest/health/1 returns expected JSON.
Import cleanup
packages/platform/platform-params/src/builder/PlatformParams.ts
Removes unused Inject, Injectable, and InjectorService imports from @tsed/di.
Test expectation change
packages/platform/platform-test-sdk/src/tests/testResponse.ts
Changes expected HTTP status for GET /rest/response/scenario15b from 401 to 404.
Vitest coverage threshold
packages/platform/platform-fastify/vitest.config.mts
Lowers branch coverage threshold from 91 to 90.52.
Koa response behavior
packages/platform/platform-koa/src/services/PlatformKoaResponse.ts
Adds private #statusCode?: number; hasStatus() now checks `this.#statusCode !== undefined
Koa response tests
packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts
Updates test expectation: hasStatus() returns true after explicitly setting status to 404.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant Fastify as FastifyMiddleware
    participant Ctx as PlatformContext
    participant Handler
    participant Next as next()

    Client->>Fastify: HTTP request

    rect rgb(220,240,255)
    Note over Fastify,Ctx: New async middleware flow
    Fastify->>Ctx: runInContext($ctx, handler)
    Ctx->>Handler: execute handler($ctx)
    Handler-->>Ctx: result
    Ctx-->>Fastify: awaited result
    end

    rect rgb(255,235,220)
    alt metadata.type == RESPONSE_FN
        Note over Fastify: skip calling next()
    else
        Fastify->>Fastify: callNext(done, metadata, $ctx)
        Fastify->>Next: next(err?) 
    end
    end

    Fastify->>Client: return handler result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Attention points:
    • packages/platform/platform-fastify/src/components/PlatformFastify.ts — verify async wrapper semantics, error propagation to done/next, and compatibility with Fastify middleware expectations.
    • packages/platform/platform-fastify/test/global-middleware.spec.ts — ensure test correctly registers global middleware and isolates side effects.
    • packages/platform/platform-koa/src/services/PlatformKoaResponse.ts — confirm #statusCode interactions and hasStatus() logic.

Possibly related PRs

  • Beta #3044 — Overlapping edits to PlatformFastify (adds PlatformContext import, callNext helper, and converts middleware wrapper to async).

Suggested reviewers

  • VictoriqueMoe

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: enhancing middleware handling in platform-fastify and adding a global middleware test, which aligns with the changeset's primary objectives.
✨ 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 fix-fastify-global-middlewares

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4220478 and e20ac8f.

📒 Files selected for processing (2)
  • packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts (1 hunks)
  • packages/platform/platform-koa/src/services/PlatformKoaResponse.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Romakita
Repo: tsedio/tsed PR: 3209
File: packages/platform/platform-fastify/src/components/PlatformFastify.ts:119-130
Timestamp: 2025-11-10T13:36:27.325Z
Learning: In the Ts.ED Fastify platform (`packages/platform/platform-fastify/src/components/PlatformFastify.ts`), the next function abstraction layer automatically handles preventing double invocations of `next()`, so explicit guards checking `metadata.hasNextFunction` are not required when calling `callNext(done, metadata, $ctx)` after middleware execution.
📚 Learning: 2024-11-28T13:04:43.555Z
Learnt from: Romakita
Repo: tsedio/tsed PR: 2900
File: packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts:6-6
Timestamp: 2024-11-28T13:04:43.555Z
Learning: Les modifications apportées aux fichiers de test internes, tels que `packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts`, sont considérées comme internes au repository et n'introduisent pas de breaking change potentiel.

Applied to files:

  • packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts
⏰ 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). (9)
  • GitHub Check: test-third-parties (20.19.4)
  • GitHub Check: test-security (20.19.4)
  • GitHub Check: test-graphql (20.19.4)
  • GitHub Check: lint (20.19.4)
  • GitHub Check: test-specs (20.19.4)
  • GitHub Check: test-orm (20.19.4)
  • GitHub Check: test-platform (20.19.4)
  • GitHub Check: test-core (20.19.4)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (4)
packages/platform/platform-koa/src/services/PlatformKoaResponse.ts (3)

17-17: Previous review comment addressed successfully.

The private field is now correctly typed as optional (#statusCode?: number;), properly reflecting that it starts uninitialized and is set only when status() is called.


38-40: Previous review comment addressed successfully.

The explicit undefined check (this.#statusCode !== undefined) now correctly handles status code 0 and distinguishes between "no status set" and "explicitly set status". The logic correctly returns true when status is explicitly set via status() or when the current status differs from the default 404.


47-52: LGTM!

The status() method correctly updates both this.raw.status and the private #statusCode field, ensuring proper tracking of explicitly set status codes. This works seamlessly with the updated hasStatus() logic.

packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts (1)

70-80: LGTM!

The test expectation correctly reflects the updated behavior. When status is explicitly set to 404 via status(), hasStatus() now returns true (because #statusCode is defined), distinguishing between an explicit status set and the default unset state. This aligns perfectly with the implementation changes in PlatformKoaResponse.ts.


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.

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

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f06f911 and feebc30.

📒 Files selected for processing (4)
  • packages/platform/platform-fastify/src/components/PlatformFastify.ts (3 hunks)
  • packages/platform/platform-fastify/test/global-middleware.spec.ts (1 hunks)
  • packages/platform/platform-params/src/builder/PlatformParams.ts (1 hunks)
  • packages/platform/platform-test-sdk/src/tests/testResponse.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-28T13:04:43.555Z
Learnt from: Romakita
Repo: tsedio/tsed PR: 2900
File: packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts:6-6
Timestamp: 2024-11-28T13:04:43.555Z
Learning: Les modifications apportées aux fichiers de test internes, tels que `packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts`, sont considérées comme internes au repository et n'introduisent pas de breaking change potentiel.

Applied to files:

  • packages/platform/platform-test-sdk/src/tests/testResponse.ts
  • packages/platform/platform-params/src/builder/PlatformParams.ts
🧬 Code graph analysis (2)
packages/platform/platform-fastify/test/global-middleware.spec.ts (3)
packages/platform/platform-test-sdk/src/components/PlatformTestSdk.ts (1)
  • PlatformTestSdk (6-31)
packages/platform/platform-fastify/src/components/PlatformFastify.ts (1)
  • PlatformFastify (48-357)
packages/platform/platform-http/src/testing/PlatformTest.ts (1)
  • PlatformTest (19-165)
packages/platform/platform-fastify/src/components/PlatformFastify.ts (2)
packages/platform/platform-router/src/domain/PlatformHandlerMetadata.ts (2)
  • PlatformHandlerMetadata (21-154)
  • handler (64-66)
packages/platform/platform-http/src/common/domain/PlatformContext.ts (1)
  • PlatformContext (25-136)
⏰ 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). (9)
  • GitHub Check: test-security (20.19.4)
  • GitHub Check: test-third-parties (20.19.4)
  • GitHub Check: test-graphql (20.19.4)
  • GitHub Check: test-specs (20.19.4)
  • GitHub Check: test-platform (20.19.4)
  • GitHub Check: lint (20.19.4)
  • GitHub Check: test-orm (20.19.4)
  • GitHub Check: test-core (20.19.4)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (4)
packages/platform/platform-test-sdk/src/tests/testResponse.ts (1)

456-456: Updated test expectation aligns with middleware handling improvements.

The change from expecting 401 to 404 for the proxied axios request suggests the middleware handling improvements now correctly propagate the actual HTTP status code from the external endpoint.

packages/platform/platform-params/src/builder/PlatformParams.ts (1)

1-1: LGTM! Valid cleanup of unused imports.

The removed imports (Inject, Injectable, InjectorService) are not referenced in the file. This reduces the dependency surface without affecting functionality.

packages/platform/platform-fastify/test/global-middleware.spec.ts (1)

1-59: LGTM! Comprehensive test coverage for global middleware integration.

The test suite properly validates:

  • Global middleware registration via the middlewares configuration option
  • Middleware execution flow with the @Next() parameter
  • Request propagation through the middleware chain to the controller endpoint
  • Correct response handling

The implementation provides good coverage for the enhanced middleware handling introduced in this PR.

packages/platform/platform-fastify/src/components/PlatformFastify.ts (1)

42-46: The callNext helper correctly handles conditional next() invocation.

The function appropriately:

  • Skips calling next() for RESPONSE_FN types (which handle their own response completion)
  • Propagates errors when present and context isn't done
  • Calls next() without arguments for successful completion

Comment on lines 119 to 130
case PlatformHandlerType.MIDDLEWARE:
return (request: IncomingMessage, _: ServerResponse, done: (err?: any) => void) => {
return async (request: IncomingMessage, _: ServerResponse, done: (err?: any) => void) => {
const {$ctx} = request;

$ctx.next = done;

return runInContext($ctx, () => handler($ctx));
const result = await runInContext($ctx, () => handler($ctx));

callNext(done, metadata, $ctx);

return result;
};
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 10, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that automatic next() invocation doesn't conflict with middleware that explicitly calls next().

The middleware wrapper now automatically calls callNext(done, metadata, $ctx) after the handler completes (line 127). However, middleware that declare the @Next() parameter (like GlobalInputMiddleware in the test file) will call next() within their handler body. This could result in next() being invoked twice:

  1. First by the middleware handler (e.g., line 33 in global-middleware.spec.ts)
  2. Then by the wrapper's callNext on line 127

The PlatformHandlerMetadata class includes a hasNextFunction property that tracks whether a middleware declares the @Next() parameter, but this property isn't being checked here.

Please verify whether this double-invocation is intentional or if callNext should only be invoked when !metadata.hasNextFunction. Run the following script to check how hasNextFunction is used elsewhere in the codebase:


🏁 Script executed:

#!/bin/bash
# Search for hasNextFunction usage to understand the pattern
rg -n -A 3 -B 3 'hasNextFunction' --type ts

Length of output: 9385





🏁 Script executed:

#!/bin/bash
# Search for callNext function implementation and usage
rg -n -A 5 -B 2 'callNext' --type ts | head -100

Length of output: 3904


🏁 Script executed:

#!/bin/bash
# Search for all handler type cases in PlatformFastify.ts to see the pattern
rg -n 'case PlatformHandlerType\.' packages/platform/platform-fastify/src/components/PlatformFastify.ts -A 10

Length of output: 390



---

🏁 Script executed:

```shell
#!/bin/bash
# Find the global-middleware.spec.ts test file and verify test coverage
fd -name 'global-middleware.spec.ts' -type f

Length of output: 230


🏁 Script executed:

#!/bin/bash
# Check ERR_MIDDLEWARE and other handler types in PlatformFastify.ts
rg -n 'case PlatformHandlerType\.(ERR_MIDDLEWARE|ENDPOINT|RESPONSE_FN)' packages/platform/platform-fastify/src/components/PlatformFastify.ts -A 12

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Find test file for middleware
find . -name '*middleware*.spec.ts' -type f | head -10

Length of output: 209


🏁 Script executed:

#!/bin/bash
# Show all handler type cases in PlatformFastify.ts
rg -n 'case PlatformHandlerType' packages/platform/platform-fastify/src/components/PlatformFastify.ts -A 12

Length of output: 410


🏁 Script executed:

#!/bin/bash
# Check if hasNextFunction is checked anywhere in PlatformFastify.ts
rg -n 'hasNextFunction' packages/platform/platform-fastify/src/components/PlatformFastify.ts

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Check global-middleware.spec.ts to see test scenarios
cat packages/platform/platform-fastify/test/global-middleware.spec.ts | head -150

Length of output: 1277


🏁 Script executed:

#!/bin/bash
# Check if there are any tests that verify next() is NOT called twice
rg -n 'next\|Next\|GlobalInputMiddleware' packages/platform/platform-fastify/test/global-middleware.spec.ts -B 2 -A 5 | head -80

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Check MIDDLEWARE case in PlatformExpress.ts to compare patterns
rg -n 'case PlatformHandlerType.MIDDLEWARE' packages/platform/platform-express/src/components/PlatformExpress.ts -A 12

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Check if hasNextFunction guard is used in PlatformExpress.ts
rg -n 'hasNextFunction' packages/platform/platform-express/src/components/PlatformExpress.ts

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Check the full PlatformFastify.ts file around the MIDDLEWARE case and other handler types
cat packages/platform/platform-fastify/src/components/PlatformFastify.ts | sed -n '100,160p'

Length of output: 1541


🏁 Script executed:

#!/bin/bash
# Search for how $ctx.next is used and if it tracks whether next was already called
rg -n '\$ctx\.next\|isDone\|isFinished' packages/platform/platform-fastify/src/components/PlatformFastify.ts -B 2 -A 2

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Search for isDone method/property to see if it prevents double invocation
rg -n 'isDone' packages/platform/platform-fastify/src -B 2 -A 2 | head -50

Length of output: 1168


🏁 Script executed:

#!/bin/bash
# Check what happens in callNext when next is called - specifically look at the done callback behavior
rg -n 'function callNext\|const callNext' packages/platform/platform-fastify/src/components/PlatformFastify.ts -A 10

Length of output: 0


🏁 Script executed:

#!/bin/bash
# See if there's any tracking of whether next was already invoked
rg -n 'next&&\|next\(' packages/platform/platform-fastify/src/components/PlatformFastify.ts -B 2 -A 2

Length of output: 0


Add guard to prevent automatic next() invocation when middleware explicitly declares @Next() parameter.

The automatic invocation of next() on line 127 conflicts with middleware that declares @Next() (via hasNextFunction). When middleware with @Next() calls next() explicitly, callNext will invoke it again unconditionally since it doesn't check hasNextFunction. This pattern is inconsistent with how other components (e.g., AnyToPromise.ts line 168) guard auto-invocation.

Fix: Modify line 127 to only invoke callNext when !metadata.hasNextFunction:

if (!metadata.hasNextFunction) {
  callNext(done, metadata, $ctx);
}
🤖 Prompt for AI Agents
In packages/platform/platform-fastify/src/components/PlatformFastify.ts around
lines 119 to 130, the middleware branch always calls callNext(done, metadata,
$ctx) causing double next() when middleware explicitly declares a @Next()
parameter; change the logic to only invoke callNext when
metadata.hasNextFunction is false (i.e., wrap the call in an if
(!metadata.hasNextFunction) check) so auto-invocation is skipped for handlers
that receive and call next() themselves.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not needed, is done by the next function abstraction layer

Copy link
Contributor

Choose a reason for hiding this comment

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

@Romakita, thank you for the clarification! I understand that the next function abstraction layer already handles preventing double invocations, so the additional guard is not necessary.


✏️ Learnings added
Learnt from: Romakita
Repo: tsedio/tsed PR: 3209
File: packages/platform/platform-fastify/src/components/PlatformFastify.ts:119-130
Timestamp: 2025-11-10T13:36:27.325Z
Learning: In the Ts.ED Fastify platform (`packages/platform/platform-fastify/src/components/PlatformFastify.ts`), the next function abstraction layer automatically handles preventing double invocations of `next()`, so explicit guards checking `metadata.hasNextFunction` are not required when calling `callNext(done, metadata, $ctx)` after middleware execution.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

…dleware test

- Introduced `callNext` utility for improved response handling in middleware.
- Refined middleware handler to support async operations and detailed error handling.
- Resolved minor issues with static handler registration.
- Added comprehensive test for global middleware integration.
@Romakita Romakita force-pushed the fix-fastify-global-middlewares branch from feebc30 to e869ebc Compare November 10, 2025 14:12
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: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between feebc30 and e869ebc.

📒 Files selected for processing (5)
  • packages/platform/platform-fastify/src/components/PlatformFastify.ts (3 hunks)
  • packages/platform/platform-fastify/test/global-middleware.spec.ts (1 hunks)
  • packages/platform/platform-fastify/vitest.config.mts (1 hunks)
  • packages/platform/platform-params/src/builder/PlatformParams.ts (1 hunks)
  • packages/platform/platform-test-sdk/src/tests/testResponse.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: Romakita
Repo: tsedio/tsed PR: 3209
File: packages/platform/platform-fastify/src/components/PlatformFastify.ts:119-130
Timestamp: 2025-11-10T13:36:27.325Z
Learning: In the Ts.ED Fastify platform (`packages/platform/platform-fastify/src/components/PlatformFastify.ts`), the next function abstraction layer automatically handles preventing double invocations of `next()`, so explicit guards checking `metadata.hasNextFunction` are not required when calling `callNext(done, metadata, $ctx)` after middleware execution.
📚 Learning: 2024-11-28T13:04:43.555Z
Learnt from: Romakita
Repo: tsedio/tsed PR: 2900
File: packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts:6-6
Timestamp: 2024-11-28T13:04:43.555Z
Learning: Les modifications apportées aux fichiers de test internes, tels que `packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts`, sont considérées comme internes au repository et n'introduisent pas de breaking change potentiel.

Applied to files:

  • packages/platform/platform-test-sdk/src/tests/testResponse.ts
  • packages/platform/platform-fastify/vitest.config.mts
  • packages/platform/platform-params/src/builder/PlatformParams.ts
📚 Learning: 2025-11-10T13:36:27.325Z
Learnt from: Romakita
Repo: tsedio/tsed PR: 3209
File: packages/platform/platform-fastify/src/components/PlatformFastify.ts:119-130
Timestamp: 2025-11-10T13:36:27.325Z
Learning: In the Ts.ED Fastify platform (`packages/platform/platform-fastify/src/components/PlatformFastify.ts`), the next function abstraction layer automatically handles preventing double invocations of `next()`, so explicit guards checking `metadata.hasNextFunction` are not required when calling `callNext(done, metadata, $ctx)` after middleware execution.

Applied to files:

  • packages/platform/platform-fastify/test/global-middleware.spec.ts
  • packages/platform/platform-fastify/src/components/PlatformFastify.ts
🧬 Code graph analysis (2)
packages/platform/platform-fastify/test/global-middleware.spec.ts (3)
packages/platform/platform-test-sdk/src/components/PlatformTestSdk.ts (1)
  • PlatformTestSdk (6-31)
packages/platform/platform-fastify/src/components/PlatformFastify.ts (1)
  • PlatformFastify (48-357)
packages/platform/platform-http/src/testing/PlatformTest.ts (1)
  • PlatformTest (19-165)
packages/platform/platform-fastify/src/components/PlatformFastify.ts (3)
packages/platform/platform-router/src/domain/PlatformHandlerMetadata.ts (2)
  • PlatformHandlerMetadata (21-154)
  • handler (64-66)
packages/platform/platform-http/src/common/domain/PlatformContext.ts (1)
  • PlatformContext (25-136)
packages/platform/platform-fastify/src/services/PlatformFastifyRequest.ts (1)
  • IncomingMessage (15-17)
⏰ 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). (9)
  • GitHub Check: CodeQL-Build
  • GitHub Check: test-graphql (20.19.4)
  • GitHub Check: test-orm (20.19.4)
  • GitHub Check: test-specs (20.19.4)
  • GitHub Check: test-security (20.19.4)
  • GitHub Check: test-third-parties (20.19.4)
  • GitHub Check: test-platform (20.19.4)
  • GitHub Check: lint (20.19.4)
  • GitHub Check: test-core (20.19.4)
🔇 Additional comments (5)
packages/platform/platform-fastify/vitest.config.mts (1)

14-14: LGTM: Coverage threshold adjustment is reasonable.

The branch coverage threshold is reduced slightly from 91% to 90.52% to accommodate the new middleware handling logic. This is a minor adjustment that reflects the added complexity in the callNext helper and async middleware wrapper.

packages/platform/platform-params/src/builder/PlatformParams.ts (1)

1-1: LGTM: Unused imports removed.

The cleanup removes Inject, Injectable, and InjectorService that are not used in this file, reducing the dependency surface without affecting behavior.

packages/platform/platform-fastify/test/global-middleware.spec.ts (1)

1-59: LGTM: Comprehensive test for global middleware integration.

This test effectively validates the enhanced middleware handling by:

  • Registering a global middleware that calls next()
  • Mounting a controller with an endpoint
  • Verifying the request flows correctly through middleware to the endpoint

The test structure follows established patterns and properly exercises the async middleware wrapper and callNext helper introduced in this PR.

packages/platform/platform-fastify/src/components/PlatformFastify.ts (1)

119-130: LGTM: Async middleware wrapper properly handles execution flow.

The changes correctly:

  • Await the handler execution within runInContext
  • Call callNext to propagate control flow or errors to the next middleware
  • Return the handler result

Based on learnings, the next function abstraction layer automatically prevents double invocations, so the automatic callNext invocation after handler execution is safe even when middleware explicitly declares @Next().

packages/platform/platform-test-sdk/src/tests/testResponse.ts (1)

455-459: Test expectation change is correct.

The external endpoint https://api.tsed.dev/rest/github/typed/test returns 404, confirming the test expectation change from 401 to 404 is accurate and justified. No action needed.

Comment on lines +42 to +46
function callNext(next: any, metadata: PlatformHandlerMetadata, $ctx: PlatformContext) {
if (metadata.type !== PlatformHandlerType.RESPONSE_FN) {
return next && $ctx.error && !$ctx.isDone() ? next($ctx.error) : next();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix potential "next is not a function" error.

The callNext helper may attempt to call next() even when next is falsy. The current logic:

return next && $ctx.error && !$ctx.isDone() ? next($ctx.error) : next();

If next is undefined or null, the ternary still evaluates to next() in the false branch, which would throw a runtime error.

Apply this diff to safely guard the invocation:

 function callNext(next: any, metadata: PlatformHandlerMetadata, $ctx: PlatformContext) {
   if (metadata.type !== PlatformHandlerType.RESPONSE_FN) {
-    return next && $ctx.error && !$ctx.isDone() ? next($ctx.error) : next();
+    if (!next) return;
+    return $ctx.error && !$ctx.isDone() ? next($ctx.error) : next();
   }
 }
🤖 Prompt for AI Agents
In packages/platform/platform-fastify/src/components/PlatformFastify.ts around
lines 42 to 46, the helper callNext may invoke next() even when next is falsy;
change the logic to only call next when it is a function — e.g. check typeof
next === 'function' before invoking, call next($ctx.error) when next is a
function and $ctx.error && ! $ctx.isDone(), otherwise call next() only if it's a
function, and return undefined when next is not callable.

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

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e869ebc and 8075394.

📒 Files selected for processing (1)
  • packages/platform/platform-koa/src/services/PlatformKoaResponse.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Romakita
Repo: tsedio/tsed PR: 3209
File: packages/platform/platform-fastify/src/components/PlatformFastify.ts:119-130
Timestamp: 2025-11-10T13:36:27.325Z
Learning: In the Ts.ED Fastify platform (`packages/platform/platform-fastify/src/components/PlatformFastify.ts`), the next function abstraction layer automatically handles preventing double invocations of `next()`, so explicit guards checking `metadata.hasNextFunction` are not required when calling `callNext(done, metadata, $ctx)` after middleware execution.
⏰ 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: test-orm (20.19.4)
  • GitHub Check: test-security (20.19.4)
  • GitHub Check: test-platform (20.19.4)
  • GitHub Check: test-specs (20.19.4)
  • GitHub Check: test-core (20.19.4)
  • GitHub Check: test-graphql (20.19.4)
🔇 Additional comments (2)
packages/platform/platform-koa/src/services/PlatformKoaResponse.ts (2)

38-40: Verify the refined status detection logic.

The updated logic correctly distinguishes between a default 404 status and an explicitly set status code. This allows the framework to determine whether the developer has explicitly called status().

Ensure that edge cases are covered in tests, particularly:

  • Explicitly setting status to 404 should return true
  • Default 404 (without calling status()) should return false
  • Other explicitly set status codes should return true

47-52: LGTM!

The implementation correctly tracks when a status code is explicitly set, enabling the refined hasStatus() detection logic. The dual assignment to both this.raw.status and this.#statusCode properly maintains both the underlying Koa response status and the tracking mechanism.

@Romakita Romakita force-pushed the fix-fastify-global-middlewares branch from 8075394 to 4220478 Compare November 10, 2025 15:08
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

♻️ Duplicate comments (1)
packages/platform/platform-koa/src/services/PlatformKoaResponse.ts (1)

17-17: Type annotation issue for uninitialized field.

The #statusCode field is declared as number but starts uninitialized (undefined), which creates a type mismatch. This has already been flagged in a previous review.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8075394 and 4220478.

📒 Files selected for processing (2)
  • packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts (1 hunks)
  • packages/platform/platform-koa/src/services/PlatformKoaResponse.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Romakita
Repo: tsedio/tsed PR: 3209
File: packages/platform/platform-fastify/src/components/PlatformFastify.ts:119-130
Timestamp: 2025-11-10T13:36:27.325Z
Learning: In the Ts.ED Fastify platform (`packages/platform/platform-fastify/src/components/PlatformFastify.ts`), the next function abstraction layer automatically handles preventing double invocations of `next()`, so explicit guards checking `metadata.hasNextFunction` are not required when calling `callNext(done, metadata, $ctx)` after middleware execution.
📚 Learning: 2024-11-28T13:04:43.555Z
Learnt from: Romakita
Repo: tsedio/tsed PR: 2900
File: packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts:6-6
Timestamp: 2024-11-28T13:04:43.555Z
Learning: Les modifications apportées aux fichiers de test internes, tels que `packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts`, sont considérées comme internes au repository et n'introduisent pas de breaking change potentiel.

Applied to files:

  • packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts
⏰ 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). (8)
  • GitHub Check: test-specs (20.19.4)
  • GitHub Check: test-orm (20.19.4)
  • GitHub Check: test-third-parties (20.19.4)
  • GitHub Check: test-graphql (20.19.4)
  • GitHub Check: test-security (20.19.4)
  • GitHub Check: test-platform (20.19.4)
  • GitHub Check: test-core (20.19.4)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (1)
packages/platform/platform-koa/src/services/PlatformKoaResponse.spec.ts (1)

76-76: Test correctly reflects new behavior.

The updated expectation aligns with the new implementation where hasStatus() returns true after explicitly setting status to 404, distinguishing it from the default Koa 404 status. This test change is correct assuming the logic bug in hasStatus() (lines 38-40 of PlatformKoaResponse.ts) is fixed.

@Romakita Romakita force-pushed the fix-fastify-global-middlewares branch from 4220478 to e20ac8f Compare November 10, 2025 15:14
@Romakita Romakita merged commit 6acb8a0 into production Nov 10, 2025
12 checks passed
@Romakita Romakita deleted the fix-fastify-global-middlewares branch November 10, 2025 15:19
@Romakita
Copy link
Collaborator Author

🎉 This PR is included in version 8.18.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants