Catch/Handle Microservice Not defined MessagePattern (RabbitMQ) NoAck/Ack?
See original GitHub issueFeature Request
If you emit to a queue a not existing CmdPattern, any Server will accept it and just dump and remove the message from the queue with. [Server] There is no matching event handler defined in the remote service.
app.useGlobalFilters(new AllExceptionsFilter());
app.useGlobalInterceptors(new LoggingInterceptor());
There is no possibility to catch the error either with, the Filters and Interceptors only get triggered if the CmdPattern / MessagePattern match.
If this happens, there is no possbility to Re-Enqueue and/or set Redelivered on the message, or move the message to a dead letter queue. It’s just dropped by a connected Nest Microservices on the queue which is might an old or not compatible with the Pattern on the Message.
So a message just get lost. Queue.Send() does not let you send the message if no receiver is registered, it’s okay but we prefer using a message broker to decuple the microservices, no checking dependence. Just put always the data into the queue.
Also would be nice to handle channel.nack(message) / channel.ack(message) in @MessagePattern({ cmd: ‘whatEver’ })
Is your feature request related to a problem? Please describe.
Exception: [Server] There is no matching event handler defined in the remote service.
https://github.com/nestjs/nest/blob/master/packages/microservices/server/server-rmq.ts
if (isUndefined((packet as IncomingRequest).id)) {
return this.handleEvent(pattern, packet, rmqContext);
}
https://github.com/nestjs/nest/blob/master/packages/microservices/server/server.ts
const handler = this.getHandlerByPattern(pattern);
if (!handler) {
return this.logger.error(NO_EVENT_HANDLER);
}
Message was passed to QueueListener/Server and just get dropped without any possiblity to handle/ack/noack/requeue/etc. because of not known MessageHandler.
Describe the solution you’d like
//HANDLE MESSAGES
@MessagePatternException({})
HandleNotSupportedMessages(exception, pattern, content, channel, message)
{
//DETECT LOOP
if(message.Redelivered){
//PUT MESSAGE TO A ERROR QUEUE
deadLetterQueue.emit(message)
//ACCEPT MESSAGE (DROP)
channel.ack(message);
}
else
{
//RE-ENQUEUE MESSAGE
channel.nack(message)
}
}
What is the motivation / use case for changing the behavior?
Messages get dropped by old version of an microservices on queue.
Sure with lots of dicipline and versioning in queue names this can maybe handled, but someone starts an old microservice is cleans a queue to the nirvana.
It’s important to have full message handling in code under control.
Cheers Otto. 🤩🚀😻
Issue Analytics
- State:
- Created 4 years ago
- Reactions:7
- Comments:6 (2 by maintainers)
Hey Kamil, yes for the start this would be very helpful, but to handle right in either in the interceptor or exception, the reference to channel an message is essential.
Otto.
Although I like this idea a lot, I don’t think it’s doable for most of the transporters we provide out-of-the-box taking into account that they typically require explicit subscriptions to specific topics. In this case, we can’t really implement a generic solution that would work for all strategies, so if anyone needs that I’d recommend checking out this chapter https://docs.nestjs.com/microservices/custom-transport (from the docs) and following it, extending a specific
ServerX
class (depending on what strategy you want to extend).