diff --git a/mocks/app/routes/directory/_error.tsx b/mocks/app/routes/directory/_error.tsx
new file mode 100644
index 0000000..11fd6fd
--- /dev/null
+++ b/mocks/app/routes/directory/_error.tsx
@@ -0,0 +1,7 @@
+import type { ErrorHandler } from 'hono'
+
+const handler: ErrorHandler = (error, c) => {
+ return c.render(
Custom Error in /directory: {error.message}
)
+}
+
+export default handler
diff --git a/mocks/app/routes/directory/sub/throw_error.tsx b/mocks/app/routes/directory/sub/throw_error.tsx
new file mode 100644
index 0000000..dc125fb
--- /dev/null
+++ b/mocks/app/routes/directory/sub/throw_error.tsx
@@ -0,0 +1,5 @@
+import { createRoute } from '../../../../../src/factory'
+
+export default createRoute(() => {
+ throw new Error('Foo')
+})
diff --git a/mocks/app/routes/directory/throw_error.tsx b/mocks/app/routes/directory/throw_error.tsx
new file mode 100644
index 0000000..bdf2fb1
--- /dev/null
+++ b/mocks/app/routes/directory/throw_error.tsx
@@ -0,0 +1,5 @@
+import { createRoute } from '../../../../src/factory'
+
+export default createRoute(() => {
+ throw new Error('Foo')
+})
diff --git a/src/server/server.ts b/src/server/server.ts
index ceefcba..7121836 100644
--- a/src/server/server.ts
+++ b/src/server/server.ts
@@ -111,6 +111,8 @@ export const createApp = (options: BaseServerOptions): Hono
return paths
}
+ const errorHandlerMap: Record = {}
+
for (const map of routesMap) {
for (const [dir, content] of Object.entries(map)) {
const subApp = new Hono<{
@@ -186,8 +188,19 @@ export const createApp = (options: BaseServerOptions): Hono
}
}
- // Error
- applyError(subApp, dir, errorMap)
+ // Get an error handler
+ const errorHandler = getErrorHandler(dir, errorMap)
+ if (errorHandler) {
+ errorHandlerMap[dir] = errorHandler
+ }
+
+ // Apply an error handler
+ for (const [path, errorHandler] of Object.entries(errorHandlerMap)) {
+ const regExp = new RegExp(`^${path}`)
+ if (regExp.test(dir) && errorHandler) {
+ subApp.onError(errorHandler)
+ }
+ }
let rootPath = getRootPath(dir)
if (trailingSlash) {
@@ -241,24 +254,23 @@ function applyNotFound(
}
}
-function applyError(
- app: Hono<{ Variables: Variables }>,
- dir: string,
- map: Record>
-) {
+function getErrorHandler(dir: string, map: Record>) {
for (const [mapDir, content] of Object.entries(map)) {
if (dir === mapDir) {
const errorFile = content[ERROR_FILENAME]
if (errorFile) {
- const errorHandler = errorFile.default
- app.onError(async (error, c) => {
- const importingIslands = errorFile[IMPORTING_ISLANDS_ID]
- if (importingIslands) {
- c.set(IMPORTING_ISLANDS_ID, importingIslands)
+ const matchedErrorHandler = errorFile.default
+ if (matchedErrorHandler) {
+ const errorHandler: ErrorHandler = async (error, c) => {
+ const importingIslands = errorFile[IMPORTING_ISLANDS_ID]
+ if (importingIslands) {
+ c.set(IMPORTING_ISLANDS_ID, importingIslands)
+ }
+ c.status(500)
+ return matchedErrorHandler(error, c)
}
- c.status(500)
- return errorHandler(error, c)
- })
+ return errorHandler
+ }
}
}
}
diff --git a/test-integration/apps.test.ts b/test-integration/apps.test.ts
index 938e193..01d7f13 100644
--- a/test-integration/apps.test.ts
+++ b/test-integration/apps.test.ts
@@ -158,6 +158,26 @@ describe('Basic', () => {
method: 'GET',
handler: expect.any(Function),
},
+ {
+ path: '/directory/throw_error',
+ method: 'GET',
+ handler: expect.any(Function),
+ },
+ {
+ path: '/directory/throw_error',
+ method: 'GET',
+ handler: expect.any(Function),
+ },
+ {
+ path: '/directory/sub/throw_error',
+ method: 'GET',
+ handler: expect.any(Function),
+ },
+ {
+ path: '/directory/sub/throw_error',
+ method: 'GET',
+ handler: expect.any(Function),
+ },
{
path: '/fc',
method: 'GET',
@@ -264,7 +284,7 @@ describe('With preserved', () => {
eager: true,
})
- const ERROR = import.meta.glob('../mocks/app/routes/_error.tsx', {
+ const ERROR = import.meta.glob('../mocks/app/routes/**/_error.tsx', {
eager: true,
})
@@ -378,6 +398,22 @@ describe('With preserved', () => {
'Internal Server ErrorCustom Error Message: Foo
'
)
})
+
+ it('Should return 500 response - /directory/throw_error', async () => {
+ const res = await app.request('/directory/throw_error')
+ expect(res.status).toBe(500)
+ expect(await res.text()).toBe(
+ 'Custom Error in /directory: Foo
'
+ )
+ })
+
+ it('Should return 500 response - /directory/sub/throw_error', async () => {
+ const res = await app.request('/directory/sub/throw_error')
+ expect(res.status).toBe(500)
+ expect(await res.text()).toBe(
+ 'Custom Error in /directory: Foo
'
+ )
+ })
})
describe('API', () => {