hono icon indicating copy to clipboard operation
hono copied to clipboard

feat(types): enhance NotFoundHandler to support custom NotFoundResponse type

Open miyaji255 opened this issue 2 months ago • 5 comments

I add a NotFoundResponse interface and support custom response types by allowing developers to extend NotFoundResponse for their own use cases.

  • [ ] Add tests
  • [ ] Run tests
  • [x] bun run format:fix && bun run lint:fix to format the code
  • [x] Add TSDoc/JSDoc to document the code

miyaji255 avatar Nov 14 '25 02:11 miyaji255

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 91.52%. Comparing base (971106d) to head (40efcf7).

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #4518      +/-   ##
==========================================
+ Coverage   91.47%   91.52%   +0.05%     
==========================================
  Files         172      172              
  Lines       11143    11221      +78     
  Branches     3224     3255      +31     
==========================================
+ Hits        10193    10270      +77     
- Misses        949      950       +1     
  Partials        1        1              

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Nov 14 '25 02:11 codecov[bot]

Hi @miyaji255

Thank you for the PR. This is super interesting. I think I know the usage, but can you share a use case of this NotFoundHandler?

yusukebe avatar Nov 14 '25 13:11 yusukebe

This is how I'm planning to type the notFound response for the client, using module augmentation. I think this pattern works well.

declare module "hono" {
  interface NotFoundResponse extends Response & TypedResponse<{ message: string}, "json", 404>{}
}

export const app = new Hono()
  .get("hoge", c => c.notFound())
  .notFound(c => c.json({ message: "Not Found" }, 404));

// And use the type with hono client
const client = hc("https://example.com/");
await client.hoge.$get() // 404 { message: string }

miyaji255 avatar Nov 14 '25 13:11 miyaji255

@miyaji255

Thank you for the explanation.

Your example should be the following:

declare module 'hono' {
  interface NotFoundResponse extends Response, TypedResponse<{ message: string }, 404, 'json'> {}
}

And, I think you should add the following patch to make it correct behavior:

diff --git a/src/context.ts b/src/context.ts
index 99bf6db9..aa32ca3d 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -756,7 +756,7 @@ export class Context<
    * })
    * ```
    */
-  notFound = (): Response | Promise<Response> => {
+  notFound = (): ReturnType<NotFoundHandler> => {
     this.#notFoundHandler ??= () => new Response()
     return this.#notFoundHandler(this)
   }
diff --git a/src/index.ts b/src/index.ts
index ba20118b..84484588 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -31,6 +31,7 @@ export type {
   Schema,
   ToSchema,
   TypedResponse,
+  NotFoundResponse,
 } from './types'
 /**
  * Types for context, context variable map, context renderer, and execution context.

yusukebe avatar Nov 18 '25 08:11 yusukebe

Hi @miyaji255

Looks good to me! I'll include this feature in the next minor version. I'll merge later. Thank you!

yusukebe avatar Dec 11 '25 09:12 yusukebe