[x] used the search to make sure that a similar issue hasn't already been submit
Expected Behavior
Should render the thrown error correctly.
Current Behavior
The thrown error is swallowed and a 500 error is thrown instead with the message "cannot wrap an error"
Possible Solution
Fix the template to not invoke h.response with an error.
Here is our workaround: Starting at line 125 of hapi.hbs, we commented out the if block:
responded++;
// next three lines are commented out to work around a bug where you cannot respond with an error, introduced by commit fc16996a067105e08e7f8abc484b2299e66dbd06 in @hapi/hapi
//if (responded == security.length && !success) {
// h.response(error).code(error.status || 401);
// }
return error;
};
Steps to Reproduce
Throw any error from the hapiAuthentication function. We happen to be throwing Boom.forbidden() and Boom.unauthorized(). This is our hapiAuthentication function:
async authorize(
request: hapi.Request,
securityName: string,
scopes: string[] = []
): Promise<any> {
if (securityName !== 'jwt') {
throw Boom.forbidden(`securityName !== "jwt"`, { securityName })
}
const authn =
request.headers[
Context.IT.opts.server.api.controllers.AuthApiController.headerKey
]
if (!authn) {
throw Boom.forbidden('no authorization bearer token')
}
const [, token] = authn?.split(' ').map((it) => it.trim())
const decodedJwt: any = jwt.verify(
token,
Context.IT.opts.server.api.controllers.AuthApiController.key,
Context.IT.signOptions
)
const user = await (
this.service || Context.IT.collectorService!
).findUserById(decodedJwt.userId)
if (!user) {
throw Boom.unauthorized('user not found', '', {
userId: decodedJwt.userId,
})
}
for (const role of user.roles) {
if (scopes.includes(role)) {
return decodedJwt
}
}
throw Boom.forbidden('user does not have required scope', {
requiredScopes: scopes,
userScopes: user.roles,
})
}
Context (Environment)
Version of the library: tsoa@3.5.1, @hapi/hapi@20.1.0
Version of NodeJS: v14.15.4
Confirm you were using yarn not npm: [ ]
We are using npm
The hapi template,
hapi.hbs
, at https://github.com/lukeautry/tsoa/blob/master/packages/cli/src/routeGeneration/templates/hapi.hbs#L128 incorrectly passes an error object toh.response
, resulting in a 500 error with text 'Cannot wrap an error' causing the loss of the original error. (see https://github.com/hapijs/hapi/blob/b8eb5f908d9cbab9769f9b79227bc9ce03c02a37/lib/toolkit.js#L191)In particular, it looks like commit https://github.com/hapijs/hapi/commit/fc16996a067105e08e7f8abc484b2299e66dbd06#diff-cd88ea53d3825cdbd93d7c9c0e50[…]4fdc45474e5facfe2cb3251abfe45R150 on 10/17/17 is what broke the tsoa
hapi.hbs
template.Sorting
I'm submitting a ...
I confirm that I
Expected Behavior
Should render the thrown error correctly.
Current Behavior
The thrown error is swallowed and a 500 error is thrown instead with the message "cannot wrap an error"
Possible Solution
Fix the template to not invoke
h.response
with an error.Here is our workaround: Starting at line 125 of
hapi.hbs
, we commented out theif
block:Steps to Reproduce
Throw any error from the
hapiAuthentication
function. We happen to be throwingBoom.forbidden()
andBoom.unauthorized()
. This is ourhapiAuthentication
function:Context (Environment)
Version of the library: tsoa@3.5.1, @hapi/hapi@20.1.0 Version of NodeJS: v14.15.4
Detailed Description
See above
Breaking change?
Unknown.