Skip to content

Conversation

@bufferings
Copy link
Owner

@bufferings bufferings commented Aug 3, 2025

Remove Response Abort Functionality and Simplify Hook Return Mechanism

This breaking change eliminates the complex abort pattern in favor of direct response returns from hooks, making the API more intuitive and reducing cognitive overhead for developers.

Changes

Core Framework (@korix/kori)

  • Remove KoriResponseAbort type and related utilities

    • Delete packages/kori/src/context/response-abort.ts
    • Remove abort() and isAborted() methods from KoriResponse
    • Remove KoriResponseAbort type and isKoriResponseAbort function
  • Update hooks to return KoriResponse directly for early termination

    • OnRequestReturnValue now accepts KoriResponse instead of KoriResponseAbort
    • KoriOnErrorHook can now return KoriResponse for error handling
    • Simplify route handler execution logic in route-handler-factory.ts

Plugins

  • Body Limit Plugin (@korix/body-limit-plugin)

    • Replace .abort() pattern with direct .badRequest() return
    • Simplify error handling for invalid Content-Length headers
  • CORS Plugin (@korix/cors-plugin)

    • Replace .abort() pattern with direct response returns
    • Use .forbidden() for origin not allowed errors
    • Use direct .empty() return for preflight responses

Documentation

  • Update all documentation to reflect new API patterns
  • Remove references to abort functionality
  • Add examples showing direct response returns from hooks

Benefits

  1. Simplified API: No more complex abort mechanism to understand
  2. Intuitive patterns: Direct response returns are more natural
  3. Reduced cognitive load: Fewer concepts for developers to learn
  4. Better TypeScript support: Cleaner type definitions

Breaking Changes

  • KoriResponseAbort type and related functions removed
  • Hook return types updated to use KoriResponse directly
  • Plugins using .abort() pattern must be updated

Migration Guide

Before:

// In hooks
return res.badRequest().abort();

// Error handling
if (res.isAborted()) return;

After:

// In hooks
return res.badRequest();

// No abort checking needed - direct returns handle early termination

Summary by CodeRabbit

  • New Features

    • Added defer() and log() methods to handler and instance context, enabling deferred processing and unified logging.
  • Bug Fixes

    • Error and response handling in plugins and middleware now use simplified helper methods for consistency and clarity.
  • Documentation

    • Updated guides and examples to reflect API changes, new logging patterns, deferred processing, and improved error handling.
    • Added new sections on documentation-only OpenAPI mode and deferred processing.
    • Refined error response formats and validation examples for clarity.
  • Refactor

    • Removed response abort mechanism; early termination is now achieved by returning a response directly from hooks.
    • Consolidated hook execution and error handling logic for improved maintainability.
  • Style

    • Unified logging calls to use ctx.log() across all examples and documentation.

This breaking change eliminates the complex abort pattern in favor of
direct response returns from hooks, making the API more intuitive and
reducing cognitive overhead for developers.

Changes:
- Remove KoriResponseAbort type and related utilities
- Update hooks to return KoriResponse directly for early termination
- Simplify route handler execution logic
- Update plugins to use direct response returns
- Update documentation to reflect new patterns
Copilot AI review requested due to automatic review settings August 3, 2025 09:15
@changeset-bot
Copy link

changeset-bot bot commented Aug 3, 2025

🦋 Changeset detected

Latest commit: d7b3394

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@korix/kori Patch
@korix/body-limit-plugin Patch
@korix/cors-plugin Patch
@korix/file-plugin-nodejs Patch
@korix/logtape-log-reporter Patch
@korix/nodejs-adapter Patch
@korix/openapi-plugin Patch
@korix/openapi-scalar-ui-plugin Patch
@korix/pino-log-reporter Patch
@korix/security-headers-plugin Patch
@korix/zod-openapi-plugin Patch
@korix/zod-schema Patch
@korix/zod-validator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Aug 3, 2025

Walkthrough

This change removes the response abort mechanism from the codebase, eliminating related types, exports, and methods. Hooks now terminate early by directly returning a KoriResponse. Documentation and plugins are updated to use ctx.defer() for deferred actions and to reflect the new hook and logging patterns. Example code and API references are revised accordingly.

Changes

Cohort / File(s) Change Summary
Core Response Abort Removal
packages/kori/src/context/response-abort.ts, packages/kori/src/context/response.ts, packages/kori/src/context/index.ts, packages/kori/src/index.ts, packages/kori/src/hook/handler-hook.ts, packages/kori/src/kori/route-handler-factory.ts
Removed all response abort types, exports, and methods. Updated hook return types to allow direct KoriResponse returns for early termination. Refactored hook execution logic to check for KoriResponse instead of abort objects.
Plugin and Middleware Refactor
packages/body-limit-plugin/src/body-limit-plugin.ts, packages/cors-plugin/src/cors-plugin.ts, docs/en/guide/plugins.md
Refactored error and preflight handling to use res.badRequest() or ctx.res.forbidden() directly, removing explicit aborts. Updated plugin examples to use deferred actions via ctx.defer() instead of separate response hooks.
Documentation: Hooks, Context, Error Handling
docs/en/guide/hooks.md, docs/en/guide/hook-execution.md, docs/en/guide/handler-context.md, docs/en/guide/instance-context.md, docs/en/guide/error-handling.md
Updated to reflect removal of abort, new hook return patterns, and unified logging via ctx.log(). Expanded and clarified error and deferred processing documentation.
Documentation: Logging, Routing, Context Evolution
docs/en/guide/logging.md, docs/en/guide/routing.md, docs/en/guide/context-evolution.md, docs/en/guide/what-is-kori.md, docs/en/guide/getting-started.md
Standardized logging patterns to use ctx.log(). Updated lifecycle hook names (onInitonStart). Revised code examples for clarity and to match current API.
Documentation: Validation and OpenAPI
docs/en/guide/request-validation.md, docs/en/guide/response-validation.md, docs/en/guide/openapi.md
Updated error response formats, validation handler examples, and clarified OpenAPI documentation-only mode. Adjusted code snippets to match the new hook and error handling patterns.
Documentation: Feature List
docs/en/index.md
Rewrote the feature list to focus on type safety, schema-driven development, and always-synchronized documentation.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant Hook as onRequest Hook
    participant Handler
    participant ErrorHook as onError Hook

    App->>Hook: Execute onRequest hooks
    alt Hook returns KoriResponse
        Hook-->>App: Return KoriResponse (early termination)
    else Continue
        Hook-->>Handler: Pass context
        Handler->>Handler: Handle request
        Handler-->>App: Return response
    end
    Note over App: If error occurs
    App->>ErrorHook: Execute onError hooks
    alt ErrorHook returns KoriResponse
        ErrorHook-->>App: Return error response
    else
        ErrorHook-->>App: Return default internal error
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

A rabbit hops through fields anew,
Where aborts are gone, and hooks are few.
Responses leap with direct grace,
Deferred tasks run in their place.
Logging’s unified, docs are clear—
Simpler code brings cheer this year!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch work

🪧 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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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

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 removes the complex response abort functionality and replaces it with a simpler pattern where hooks can return KoriResponse objects directly for early termination. This breaking change eliminates the need for the .abort() method and related utilities, making the API more intuitive.

Key changes:

  • Remove KoriResponseAbort type and related utilities from the core framework
  • Update hook return types to accept KoriResponse directly instead of KoriResponseAbort
  • Simplify route handler execution logic to handle direct response returns from hooks
  • Update plugins to use direct response returns instead of the abort pattern

Reviewed Changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/kori/src/kori/route-handler-factory.ts Refactored hook execution to handle direct response returns and simplified control flow
packages/kori/src/index.ts Removed exports for KoriResponseAbort type and utilities
packages/kori/src/hook/handler-hook.ts Updated hook return types to accept KoriResponse instead of KoriResponseAbort
packages/kori/src/context/response.ts Removed abort() and isAborted() methods from KoriResponse interface
packages/kori/src/context/response-abort.ts Deleted entire file containing abort functionality
packages/kori/src/context/index.ts Removed abort-related exports
packages/cors-plugin/src/cors-plugin.ts Updated to return responses directly instead of using abort pattern
packages/body-limit-plugin/src/body-limit-plugin.ts Updated to return responses directly instead of using abort pattern
docs/en/*.md Updated documentation to reflect new API patterns
.changeset/remove-response-abort.md Added changeset for the breaking change
Comments suppressed due to low confidence (6)

packages/kori/src/kori/route-handler-factory.ts:95

  • The variable name 'isAborted' no longer accurately reflects its purpose since the abort mechanism has been removed. Consider renaming to 'isEarlyResponse' or 'hasDirectResponse' to better describe that a hook returned a response directly.
    let isAborted = false;

packages/kori/src/kori/route-handler-factory.ts:101

  • The variable assignment 'isAborted = true' should be updated to match the renamed variable (e.g., 'isEarlyResponse = true') to maintain consistency with the new naming convention.
          isAborted = true;

packages/kori/src/kori/route-handler-factory.ts:109

  • The condition '!isAborted' should be updated to use the renamed variable (e.g., '!isEarlyResponse') to maintain consistency with the new naming convention.
      if (!isAborted) {

packages/kori/src/kori/route-handler-factory.ts:113

  • [nitpick] For consistency with the proposed renaming of 'isAborted', consider renaming 'isErrHandled' to 'hasErrorResponse' to follow the same naming pattern that describes what happened rather than a state flag.
      let isErrHandled = false;

packages/kori/src/kori/route-handler-factory.ts:118

  • [nitpick] If 'isErrHandled' is renamed to 'hasErrorResponse', this assignment should be updated accordingly for consistency.
            isErrHandled = true;

packages/kori/src/kori/route-handler-factory.ts:129

  • [nitpick] If 'isErrHandled' is renamed to 'hasErrorResponse', this condition should be updated to '!hasErrorResponse' for consistency.
      if (!isErrHandled) {

@bufferings bufferings merged commit aaeb0cc into main Aug 3, 2025
1 check was pending
@bufferings bufferings deleted the work branch August 3, 2025 09:19
Copy link

@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

🔭 Outside diff range comments (2)
docs/en/guide/handler-context.md (1)

138-141: await used inside non-async handler – code will throw

await cannot be used in a non-async arrow function.

-app.delete('/users/:id', (ctx) => {
+app.delete('/users/:id', async (ctx) => {
   await ctx.env.db.deleteUser(ctx.req.pathParams().id);
   return ctx.res.status(204).empty();
 });
docs/en/guide/logging.md (1)

51-59: Undefined error variable in logging example

error is not declared in the snippet, causing confusion. Wrap the call in a try/catch or rename the placeholder:

app.get('/example', async (ctx) => {
  const logger = ctx.log();

  try {
    // … your code
  } catch (err) {
    logger.error('Database connection failed', { err });
  }

  return ctx.res.json({ result: 'ok' });
});
🧹 Nitpick comments (3)
docs/en/guide/getting-started.md (1)

84-86: Remove non-critical bold formatting

Guideline: avoid bold for emphasis unless it’s a warning.

- **`app.log()`** - Application-level logger (outside of Kori context)
- **`ctx.log()`** - Context-aware logger (inside Kori context: hooks and handlers)
+`app.log()` – Application-level logger (outside Kori context)  
+`ctx.log()` – Context-aware logger (inside Kori context: hooks and handlers)
docs/en/guide/handler-context.md (1)

18-23: Optional: clarify defer callback type

If KoriLogger is imported elsewhere the code is fine; otherwise mention it’s from @korix/kori/logger. Consider adding an import in the snippet for newcomers.

docs/en/guide/logging.md (1)

90-100: Minor inconsistency in sample output

"userId": "1" does not match the earlier log call that used '123'. Update for consistency.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f2d81de and d7b3394.

📒 Files selected for processing (24)
  • .changeset/remove-response-abort.md (1 hunks)
  • docs/en/guide/context-evolution.md (4 hunks)
  • docs/en/guide/error-handling.md (2 hunks)
  • docs/en/guide/getting-started.md (2 hunks)
  • docs/en/guide/handler-context.md (4 hunks)
  • docs/en/guide/hook-execution.md (8 hunks)
  • docs/en/guide/hooks.md (4 hunks)
  • docs/en/guide/instance-context.md (2 hunks)
  • docs/en/guide/logging.md (5 hunks)
  • docs/en/guide/openapi.md (1 hunks)
  • docs/en/guide/plugins.md (4 hunks)
  • docs/en/guide/request-validation.md (4 hunks)
  • docs/en/guide/response-validation.md (5 hunks)
  • docs/en/guide/routing.md (1 hunks)
  • docs/en/guide/what-is-kori.md (1 hunks)
  • docs/en/index.md (1 hunks)
  • packages/body-limit-plugin/src/body-limit-plugin.ts (1 hunks)
  • packages/cors-plugin/src/cors-plugin.ts (1 hunks)
  • packages/kori/src/context/index.ts (0 hunks)
  • packages/kori/src/context/response-abort.ts (0 hunks)
  • packages/kori/src/context/response.ts (0 hunks)
  • packages/kori/src/hook/handler-hook.ts (2 hunks)
  • packages/kori/src/index.ts (0 hunks)
  • packages/kori/src/kori/route-handler-factory.ts (2 hunks)
💤 Files with no reviewable changes (4)
  • packages/kori/src/context/index.ts
  • packages/kori/src/index.ts
  • packages/kori/src/context/response-abort.ts
  • packages/kori/src/context/response.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/.changeset/*.md

📄 CodeRabbit Inference Engine (.cursor/rules/changeset.mdc)

**/.changeset/*.md: AI creates a .changeset/[descriptive-name].md file for each release-worthy change
Each changeset file must use patch/minor/major to indicate the type of change
Each changeset file must include a clear description in English
Changeset descriptions should focus on the difference relative to the original baseline, not just current working changes

Files:

  • .changeset/remove-response-abort.md
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/coding.mdc)

**/*.{ts,tsx}: Always use type modifier for type imports
Prefer type over interface
Use never as default type parameter instead of {}
Keep related types together

Files:

  • packages/body-limit-plugin/src/body-limit-plugin.ts
  • packages/cors-plugin/src/cors-plugin.ts
  • packages/kori/src/hook/handler-hook.ts
  • packages/kori/src/kori/route-handler-factory.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/coding.mdc)

**/*.{js,ts,jsx,tsx}: Always include .js extension in import paths for ESM compatibility
Use function declarations for framework public APIs
Avoid arrow functions for public APIs
Export public APIs at the end of the file
Use camelCase for function names, variable names, and property names
For abbreviations in camelCase, treat them as regular words (e.g., APIApi, UIUi, URLUrl, HTTPHttp)
Plugin function names should follow the pattern <name>Plugin in camelCase
Avoid inconsistent casing like scalarUIPlugin or openAPIPlugin
Use ESM (ECMAScript Modules) format
Include file extensions in import paths
Prefer functions over classes
Use composition over inheritance
Avoid using 'this' keyword
Source code files (.ts, .js, .tsx, .jsx) must contain only ASCII characters
Non-ASCII characters (emojis, Japanese, etc.) are prohibited in source code

Files:

  • packages/body-limit-plugin/src/body-limit-plugin.ts
  • packages/cors-plugin/src/cors-plugin.ts
  • packages/kori/src/hook/handler-hook.ts
  • packages/kori/src/kori/route-handler-factory.ts
**/*.{md,mdc,MD,MDX,README,README.md,README.mdc}

📄 CodeRabbit Inference Engine (.cursor/rules/coding.mdc)

Documentation files (.md, .mdc, README) may use non-ASCII characters freely

Files:

  • docs/en/index.md
  • docs/en/guide/what-is-kori.md
  • docs/en/guide/response-validation.md
  • docs/en/guide/context-evolution.md
  • docs/en/guide/routing.md
  • docs/en/guide/logging.md
  • docs/en/guide/instance-context.md
  • docs/en/guide/error-handling.md
  • docs/en/guide/openapi.md
  • docs/en/guide/request-validation.md
  • docs/en/guide/handler-context.md
  • docs/en/guide/hook-execution.md
  • docs/en/guide/getting-started.md
  • docs/en/guide/hooks.md
  • docs/en/guide/plugins.md
**/docs/**/*.md

📄 CodeRabbit Inference Engine (.cursor/rules/docs.mdc)

**/docs/**/*.md: Never write documentation based on assumptions or guesswork; always read and understand the actual source code before writing documentation, including reading main API functions, type definitions, and existing examples, verifying all code examples work with the actual implementation, basing method signatures and behaviors on real source code, and checking test files for usage patterns.
Use clear heading hierarchy and natural prose instead of bold text for emphasis; use descriptive subheadings and logical organization, complete sentences that flow naturally, and avoid bold text for emphasis except for critical warnings.
Start documentation with the simplest working example, focus on the essential value proposition, let code examples do the explaining, and keep explanatory text concise.
State capabilities factually without overselling, avoid negative comparisons with other frameworks, never fabricate testimonials or quotes, and be positive but realistic about limitations.
Inaccurate documentation is worse than no documentation. Always verify against source code.

Files:

  • docs/en/index.md
  • docs/en/guide/what-is-kori.md
  • docs/en/guide/response-validation.md
  • docs/en/guide/context-evolution.md
  • docs/en/guide/routing.md
  • docs/en/guide/logging.md
  • docs/en/guide/instance-context.md
  • docs/en/guide/error-handling.md
  • docs/en/guide/openapi.md
  • docs/en/guide/request-validation.md
  • docs/en/guide/handler-context.md
  • docs/en/guide/hook-execution.md
  • docs/en/guide/getting-started.md
  • docs/en/guide/hooks.md
  • docs/en/guide/plugins.md
🧠 Learnings (5)
📚 Learning: applies to **/docs/**/*.md : state capabilities factually without overselling, avoid negative compar...
Learnt from: CR
PR: bufferings/kori#0
File: .cursor/rules/docs.mdc:0-0
Timestamp: 2025-08-03T04:22:54.800Z
Learning: Applies to **/docs/**/*.md : State capabilities factually without overselling, avoid negative comparisons with other frameworks, never fabricate testimonials or quotes, and be positive but realistic about limitations.

Applied to files:

  • docs/en/index.md
📚 Learning: applies to **/.changeset/*.md : changeset descriptions should focus on the difference relative to th...
Learnt from: CR
PR: bufferings/kori#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-08-03T04:22:43.611Z
Learning: Applies to **/.changeset/*.md : Changeset descriptions should focus on the difference relative to the original baseline, not just current working changes

Applied to files:

  • docs/en/index.md
📚 Learning: applies to **/readme.md : state capabilities factually without overselling, avoid negative compariso...
Learnt from: CR
PR: bufferings/kori#0
File: .cursor/rules/docs.mdc:0-0
Timestamp: 2025-08-03T04:22:54.800Z
Learning: Applies to **/README.md : State capabilities factually without overselling, avoid negative comparisons with other frameworks, never fabricate testimonials or quotes, and be positive but realistic about limitations.

Applied to files:

  • docs/en/index.md
📚 Learning: applies to **/.changeset/*.md : ai creates a `.changeset/[descriptive-name].md` file for each releas...
Learnt from: CR
PR: bufferings/kori#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-08-03T04:22:43.611Z
Learning: Applies to **/.changeset/*.md : AI creates a `.changeset/[descriptive-name].md` file for each release-worthy change

Applied to files:

  • docs/en/index.md
📚 Learning: applies to **/docs/**/*.md : use clear heading hierarchy and natural prose instead of bold text for ...
Learnt from: CR
PR: bufferings/kori#0
File: .cursor/rules/docs.mdc:0-0
Timestamp: 2025-08-03T04:22:54.800Z
Learning: Applies to **/docs/**/*.md : Use clear heading hierarchy and natural prose instead of bold text for emphasis; use descriptive subheadings and logical organization, complete sentences that flow naturally, and avoid bold text for emphasis except for critical warnings.

Applied to files:

  • docs/en/index.md
🧬 Code Graph Analysis (6)
docs/en/guide/what-is-kori.md (1)
packages/kori/src/kori/kori-internal.ts (1)
  • onStart (124-127)
docs/en/guide/response-validation.md (1)
packages/kori/src/context/response.ts (1)
  • notFound (338-347)
packages/kori/src/hook/handler-hook.ts (3)
packages/kori/src/context/handler-context.ts (1)
  • KoriHandlerContext (8-21)
packages/kori/src/context/response.ts (3)
  • KoriResponse (35-71)
  • abort (437-440)
  • createKoriResponse (447-460)
packages/kori/src/util/maybe-promise.ts (1)
  • MaybePromise (1-1)
docs/en/guide/openapi.md (2)
packages/openapi-plugin/src/openapi-plugin.ts (1)
  • openApiPlugin (52-138)
packages/openapi-scalar-ui-plugin/src/scalar-ui-plugin.ts (2)
  • apply (28-52)
  • scalarUiPlugin (20-54)
docs/en/guide/hook-execution.md (1)
packages/kori/src/context/handler-context.ts (2)
  • executeHandlerDeferredCallbacks (107-122)
  • defer (65-67)
packages/kori/src/kori/route-handler-factory.ts (4)
packages/kori/src/context/response.ts (1)
  • isKoriResponse (85-87)
packages/kori/src/index.ts (2)
  • isKoriResponse (7-7)
  • err (124-124)
packages/kori/src/logging/error-serializer.ts (1)
  • serializeError (5-38)
packages/kori/src/context/handler-context.ts (1)
  • executeHandlerDeferredCallbacks (107-122)
🪛 LanguageTool
docs/en/guide/getting-started.md

[style] ~84-~84: This phrase is redundant. Consider using “outside”.
Context: ...pp.log()** - Application-level logger (outside of Kori context) - **ctx.log()`** - Conte...

(OUTSIDE_OF)

🔇 Additional comments (39)
docs/en/guide/what-is-kori.md (1)

20-20: LGTM! Hook naming improvement aligned with framework updates.

The change from onInit to onStart improves the clarity of the lifecycle hook naming and aligns with the broader API updates across the documentation.

docs/en/guide/context-evolution.md (2)

12-12: LGTM! Lifecycle hook naming improvement.

The transition from onInit to onStart provides more intuitive naming for the lifecycle hook and aligns with the framework's API evolution.

Also applies to: 29-29


23-23: LGTM! Simplified logging API.

The change from ctx.req.log() to ctx.log() simplifies the logging interface by providing direct access to logging on the context object, reducing the need to traverse through the request object.

Also applies to: 54-54, 74-74

docs/en/guide/routing.md (1)

120-120: LGTM! Consistent logging API simplification.

The change to ctx.log() maintains the same functionality while providing a more direct and intuitive logging interface, consistent with the broader API improvements across the documentation.

packages/body-limit-plugin/src/body-limit-plugin.ts (1)

235-238: LGTM! Successful removal of abort pattern in favor of direct response return.

This change effectively implements the PR's core objective by replacing the complex .abort() pattern with a direct return of res.badRequest(). The new approach:

  • Simplifies the API by eliminating the need for explicit abort calls
  • Uses standardized error response methods that handle status and JSON formatting
  • Maintains the same error information (message and code)
  • Provides cleaner early termination from hooks
docs/en/guide/response-validation.md (5)

54-56: LGTM! Standardized error response method usage.

The change to ctx.res.notFound() provides a more standardized and concise way to return 404 errors, replacing manual status and JSON setting with a purpose-built method.


70-70: LGTM! Documentation formatting improvement.

The note formatting is cleaner without the leading asterisk while maintaining the same informational content.


152-152: LGTM! Consistent logging API simplification.

The transition to ctx.log() provides a more direct and intuitive logging interface, consistent with the broader API improvements across the framework.

Also applies to: 176-176


159-159: LGTM! Standardized internal error response.

Using ctx.res.internalError() provides a consistent way to return 500 errors with standardized formatting, replacing manual status and JSON construction.


192-192: LGTM! Accurate handler behavior description.

The updated description correctly reflects the new hook execution pattern where handlers terminate by returning a response directly rather than relying on an abort mechanism, aligning with the PR's core objective.

docs/en/index.md (1)

17-24: LGTM! Clear and accurate feature descriptions.

The updated feature list provides specific, developer-focused benefits that align well with the framework's capabilities. The descriptions are factual and avoid overselling, which follows the documentation guidelines. The emphasis on type safety, schema-driven development, and synchronized documentation effectively communicates the value proposition.

.changeset/remove-response-abort.md (1)

1-9: LGTM! Well-structured changeset.

The changeset correctly documents the removal of the response abort functionality with appropriate patch-level versioning for all affected packages. The description clearly explains the change from abort pattern to direct response returns, focusing on the difference from the baseline as required by the guidelines.

packages/cors-plugin/src/cors-plugin.ts (2)

176-179: LGTM! Simplified CORS error response.

The change from manual status setting, JSON construction, and explicit abort to using ctx.res.forbidden() with structured data is much cleaner. This aligns perfectly with the removal of the abort pattern and makes the code more intuitive.


186-186: LGTM! Clean preflight response handling.

Returning the response directly instead of using the abort pattern simplifies the control flow and makes the code more readable. This change is consistent with the new hook return mechanism.

docs/en/guide/openapi.md (1)

312-380: LGTM! Excellent documentation-only mode example.

The new section provides clear, practical guidance for using OpenAPI documentation without runtime validation. The example is complete and realistic, showing proper usage patterns including manual data access and the limitations of this approach. The explanation is factual and well-structured, following the documentation guidelines effectively.

packages/kori/src/hook/handler-hook.ts (2)

15-15: LGTM! Correct type update for simplified response handling.

The change from KoriResponseAbort to KoriResponse in the OnRequestReturnValue union correctly implements the new hook return mechanism. This allows hooks to return response objects directly for early termination, eliminating the need for the abort pattern.


28-28: LGTM! Enhanced error hook capabilities.

Adding KoriResponse to the KoriOnErrorHook return type allows error hooks to provide response handling in addition to just void returns. This enhances the flexibility of error handling while maintaining backward compatibility.

docs/en/guide/hook-execution.md (1)

21-34: Documentation update looks correct

Examples compile and accurately reflect the new “return a response to short-circuit” semantics introduced by the PR. No further action needed.

Also applies to: 53-57, 104-116

docs/en/guide/request-validation.md (1)

150-168: Validation guide aligns with new error format

The revised JSON examples and handler snippets match the updated API (ctx.res.badRequest(), nested error object). Looks good.

Also applies to: 184-206, 213-224, 235-236

docs/en/guide/instance-context.md (4)

12-19: LGTM! Clear documentation of new API methods.

The addition of defer() and log() methods to the KoriInstanceContext type definition is well-documented with proper TypeScript signatures.


23-23: Good terminology improvement.

Changing from "Perfect for" to "Used for" provides clearer, more direct documentation language.


31-31: Consistent lifecycle hook naming.

The change from onInit() to onStart() aligns with the framework's updated lifecycle hook naming convention.

Also applies to: 35-35


75-99: Excellent demonstration of the defer pattern.

The updated shutdown example clearly shows how to use ctx.defer() for cleanup tasks, with proper async handling and logging via ctx.log().

packages/kori/src/kori/route-handler-factory.ts (3)

3-3: Correct import for response type checking.

The addition of isKoriResponse import aligns with the new pattern of directly returning response objects from hooks.


95-107: Clean implementation of early termination pattern.

The refactored request hook execution correctly handles early termination by checking if the hook returns a KoriResponse and setting the isAborted flag appropriately.


113-134: Robust error handling with proper logging.

The error hook execution includes proper error catching for hook failures and logs them appropriately using the system logger. The pattern of allowing error hooks to return a KoriResponse provides flexible error handling.

docs/en/guide/error-handling.md (4)

3-3: Clear and accurate description of error handling.

The updated descriptions correctly state that error methods return JSON bodies, removing the misleading "automatic content negotiation" reference.

Also applies to: 7-7


44-48: Good addition of new error methods.

The addition of unsupportedMediaType() and timeout() methods provides more comprehensive error handling options.


56-101: Excellent documentation of error response formats.

The expanded section clearly distinguishes between default and custom error responses with helpful JSON examples.


110-110: Consistent logging pattern.

The change from ctx.req.log() to ctx.log() aligns with the unified logging API across the framework.

docs/en/guide/hooks.md (4)

13-13: Clear documentation of enhanced hook capabilities.

The updated descriptions accurately reflect that hooks now handle both initialization/processing and cleanup through the defer mechanism.

Also applies to: 19-20


26-26: Consistent use of framework logging.

Replacing console.log with ctx.log().info demonstrates proper use of the framework's logging API.

Also applies to: 39-39, 50-50


38-51: Good use of closure pattern for deferred cleanup.

The defer callback correctly uses closure variables (db, redis) instead of receiving ctx as a parameter, which is cleaner and avoids potential context issues.


69-96: Comprehensive request lifecycle example.

The enhanced example effectively demonstrates request timing, logging, and deferred cleanup with practical metrics recording placeholder.

docs/en/guide/plugins.md (5)

30-30: Accurate hook lifecycle documentation.

The change from "onRequest, onResponse" to "onRequest, onError" correctly reflects the updated hook types available in the framework.


52-69: Excellent demonstration of the defer pattern in plugins.

The logging plugin example clearly shows how to use ctx.defer() to consolidate response logging into the onRequest hook, eliminating the need for a separate onResponse hook.


195-200: Clean timestamp plugin implementation.

The simplified implementation using ctx.defer() for header setting is more concise and follows the new pattern consistently.


225-225: Consistent plugin naming convention.

Changing from "requestId" to "request-id" follows kebab-case convention for plugin names.


227-236: Well-structured request ID plugin.

The implementation correctly uses ctx.defer() to set the response header after the request ID is available on the context.

Comment on lines +109 to 111
if (!isAborted) {
await mainHandler(currentCtx);
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify response object is set when hooks return early.

When isAborted is true (a hook returned a response), ensure that currentCtx.res is properly set to the returned response object.


🏁 Script executed:

#!/bin/bash
# Description: Verify that when hooks return a KoriResponse, it's properly assigned to ctx.res

# Search for where the returned response is assigned to ctx.res
ast-grep --pattern 'if (isKoriResponse(result)) {
  $$$
}'

# Also check the hook execution flow
rg -A 10 'isKoriResponse.*result' packages/kori/src/

Length of output: 2335


Assign returned hook responses to the context before abort

To ensure that a KoriResponse returned by a hook is actually sent back, you need to store it on currentCtx.res in both early‐return branches:

• In the pre‐main hook loop (around lines 100–103 of packages/kori/src/kori/route-handler-factory.ts):

 if (isKoriResponse(result)) {
+  currentCtx.res = result;
   isAborted = true;
   break;
 }

• In the error‐hook loop (around lines 117–120):

 if (isKoriResponse(result)) {
+  currentCtx.res = result;
   isErrHandled = true;
   break;
 }

This change ensures that when hooks abort normal flow—or handle errors by returning a response—that response is assigned to the context and ultimately returned to the client.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!isAborted) {
await mainHandler(currentCtx);
}
// … around lines 100–103, in the pre-main hook loop …
for (const hook of preMainHooks) {
const result = await hook(currentCtx);
if (isKoriResponse(result)) {
currentCtx.res = result;
isAborted = true;
break;
}
}
// … lines 109–111 …
if (!isAborted) {
await mainHandler(currentCtx);
}
// … around lines 117–120, in the error-hook loop …
for (const hook of errorHooks) {
const result = await hook(currentCtx);
if (isKoriResponse(result)) {
currentCtx.res = result;
isErrHandled = true;
break;
}
}
🤖 Prompt for AI Agents
In packages/kori/src/kori/route-handler-factory.ts around lines 109 to 111, the
code calls mainHandler only if not aborted but does not assign any hook-returned
KoriResponse to currentCtx.res in the early-return branches. To fix this, update
the pre-main hook loop (around lines 100-103) and the error-hook loop (around
lines 117-120) to assign any KoriResponse returned by hooks to currentCtx.res
before aborting, ensuring the response is properly sent back to the client.

@coderabbitai coderabbitai bot mentioned this pull request Nov 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants