0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-21 18:18:57 +01:00

feat(http-exception): Add a "cause" option to HTTPException (#2224)

This commit is contained in:
Karibash 2024-02-25 19:07:33 +09:00 committed by GitHub
parent 4b3cd3c6e1
commit ce2a2f5964
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 7 deletions

View File

@ -3,6 +3,7 @@ import type { StatusCode } from './utils/http-status.ts'
type HTTPExceptionOptions = { type HTTPExceptionOptions = {
res?: Response res?: Response
message?: string message?: string
cause?: unknown
} }
/** /**
@ -26,11 +27,13 @@ type HTTPExceptionOptions = {
export class HTTPException extends Error { export class HTTPException extends Error {
readonly res?: Response readonly res?: Response
readonly status: StatusCode readonly status: StatusCode
constructor(status: StatusCode = 500, options?: HTTPExceptionOptions) { constructor(status: StatusCode = 500, options?: HTTPExceptionOptions) {
super(options?.message) super(options?.message, { cause: options?.cause })
this.res = options?.res this.res = options?.res
this.status = status this.status = status
} }
getResponse(): Response { getResponse(): Response {
if (this.res) { if (this.res) {
return this.res return this.res

View File

@ -1,15 +1,34 @@
import { HTTPException } from './http-exception' import { HTTPException } from './http-exception'
describe('HTTPFatalError', () => { describe('HTTPException', () => {
it('Should be 401 HTTP exception object', () => { it('Should be 401 HTTP exception object', async () => {
// We should throw an exception if is not authorized // We should throw an exception if is not authorized
// because next handlers should not be fired. // because next handlers should not be fired.
const exception = new HTTPException(401, { const exception = new HTTPException(401, {
message: 'Unauthorized', message: 'Unauthorized',
}) })
const res = exception.getResponse()
expect(res.status).toBe(401)
expect(await res.text()).toBe('Unauthorized')
expect(exception.status).toBe(401) expect(exception.status).toBe(401)
expect(exception.message).toBe('Unauthorized') expect(exception.message).toBe('Unauthorized')
})
it('Should be accessible to the object causing the exception', async () => {
// We should pass the cause of the error to the cause option
// because it makes debugging easier.
const error = new Error('Server Error')
const exception = new HTTPException(500, {
message: 'Internal Server Error',
cause: error,
})
const res = exception.getResponse() const res = exception.getResponse()
expect(res.status).toBe(401)
expect(res.status).toBe(500)
expect(await res.text()).toBe('Internal Server Error')
expect(exception.status).toBe(500)
expect(exception.message).toBe('Internal Server Error')
expect(exception.cause).toBe(error)
}) })
}) })

View File

@ -3,6 +3,7 @@ import type { StatusCode } from './utils/http-status'
type HTTPExceptionOptions = { type HTTPExceptionOptions = {
res?: Response res?: Response
message?: string message?: string
cause?: unknown
} }
/** /**
@ -26,11 +27,13 @@ type HTTPExceptionOptions = {
export class HTTPException extends Error { export class HTTPException extends Error {
readonly res?: Response readonly res?: Response
readonly status: StatusCode readonly status: StatusCode
constructor(status: StatusCode = 500, options?: HTTPExceptionOptions) { constructor(status: StatusCode = 500, options?: HTTPExceptionOptions) {
super(options?.message) super(options?.message, { cause: options?.cause })
this.res = options?.res this.res = options?.res
this.status = status this.status = status
} }
getResponse(): Response { getResponse(): Response {
if (this.res) { if (this.res) {
return this.res return this.res

View File

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ES2020", "target": "ES2022",
"declaration": true, "declaration": true,
"moduleResolution": "Bundler", "moduleResolution": "Bundler",
"outDir": "./dist", "outDir": "./dist",
@ -25,4 +25,4 @@
"src/**/*.test.ts", "src/**/*.test.ts",
"src/**/*.test.tsx" "src/**/*.test.tsx"
], ],
} }