#I am encountering an error – incorrect usage of the Fastify reply object

18 messages · Page 1 of 1 (latest)

unique pier
#

The error I am encountering – TypeError: response.status is not a function – suggests that the response object from Fastify is not behaving as expected. This can happen due to a few reasons, including incorrect usage of the Fastify reply object, or possible conflicts in the response lifecycle.

I have also took into consideration this Warning

If you are using @nestjs/platform-fastify you can use response.send() instead of response.json(). Don't forget to import the correct types from fastify.`

Here is the code
`@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
constructor(private logger: LoggerService) {}

async catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const res = ctx.getResponse<FastifyReply>();
const req = ctx.getRequest<FastifyRequest>();

const status = exception.getStatus?.() || 500;
const errorResponse = {
  status,
  message: exception.message || 'Unexpected error',
  path: req.url,
  method: req.method,
  timestamp: new Date().toISOString(),
};

const [sec, nano] = process.hrtime();
const responseTime = sec * 1e3 + nano / 1e6;

this.logError(status, responseTime, req, exception, errorResponse);
res.status(status).send(errorResponse);

}

private logError(status: number, time: number, req: FastifyRequest, ex: HttpException, errRes: any) {
const logData = { status, time: time.toFixed(3), path: req.url, msg: ex.message };
this.logger.error(status === 404 ? 'API Error' : 'Handled Exception', logData);
}
}`

I have tried to use the httpAdapter as well:
httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);

quartz night
#

In the main.ts you have NestFactory.create(AppModule, new FastifyAdapter()), right?

unique pier
unique pier
quartz night
#

And if you console.log(res) what are you getting?

unique pier
# quartz night And if you `console.log(res)` what are you getting?

a ServerResponse

ServerResponse {_events: {…}, _eventsCount: 1, _maxListeners: undefined, outputData: Array(0), outputSize: 0, …}
_closed =
false
_contentLength =
null
_defaultKeepAlive =
true
_events =
{finish: ƒ}
_eventsCount =
1
_expect_continue =
false ......etc

i think it is FastifyReply

quartz night
#

Interesting. ServerResponse is the raw Node response object, not the wrapped fastify resply

unique pier
#

the weird thing is if the exception is HttpStatus Not found
(like the route is not exists)
{{baseUrl}}/api/login/<not-found-route>
Fastify reply
Reply {raw: ServerResponse, request: _Request, log: {…}, Symbol(fastify.reply.isError): false, Symbol(fastify.reply.errorHandlerCalled): false, …}
context =
ƒ () {\n return this.request[kRouteContext]\n }
log =
{child: ƒ, Symbol(fastify.disableRequestLogging): false}
raw =
ServerResponse {_events: {…}, _eventsCount: 1, _maxListeners: undefined, outputData: Array(0), outputSize: 0, …}
request =
_Request {id: 'req-3', params: {…}, raw: IncomingMessage, query: {…}, log: {…}, …}
sent =
ƒ () {\n // We are checking whether reply was hijacked or the response has ended.\n return (this[kReplyHijacked] || this.raw.writableEnded) === true\n }
server =
ƒ () {\n return this.request[kRouteContext].server\n }
statusCode =
ƒ () {\n return this.raw.statusCode\n }
Symbol(fastify.context) =
ƒ () {\n return this.request[kRouteContext]\n }
Symbol(fastify.reply.endTime) =
undefined
Symbol(fastify.reply.errorHandlerCalled) =
false
Symbol(fastify.reply.headers) =
{vary: 'Origin', access-control-allow-origin: '*'}
Symbol(fastify.reply.hijacked) =
false
........etc

#

but if it is difference exception i will got as u said the Node response

quartz night
#

What are you doing to get this error thrown/caught?

unique pier
# quartz night What are you doing to get this error thrown/caught?

I am trying to have a global Exception Filter , so i was trying to test ...

first i did Api notFound error i catch the error all is good !
second test i am trying to catch InvalidToken Signature

so the exception object is

message =
'Invalid token'
name =
'UnauthorizedException'
options =
{}
response =
{status: 401, type: 'invalidToken', message: 'Invalid token'}
status =
401
stack =
'UnauthorizedException: Invalid token\n at TokenService.verifyToken (......<project path>...../node_modules/@nestjs/core/router/router-proxy.js:9:17'
[[Prototype]] =
HttpException

quartz night
#

How is it being thrown? I'm just trying to make sure I understand the whole picture here

unique pier
unique pier
quartz night
#

Hmm, I mean that all looks fine. I don't see why the response object wouldn't be a FastifyReply

#

Can you create a reproduction that shows this?

unique pier
#

will do and will let you know , Thanks for your Help 🙂

unique pier
#

@quartz night I think i have solved the problem , insted of throwing an error

throw new UnauthorizedException({
status: HttpStatus.UNAUTHORIZED,
type: 'invalidToken',
message,
});
i just return the error
return new UnauthorizedException({
status: HttpStatus.UNAUTHORIZED,
type: 'invalidToken',
message,
});

dose this make sense !