使用发布者/订阅者模式并在订阅者处理期间抛出异常时,默认情况下,EasyNetQ会在EasyNetQ_Default_Error_Queue中发送消息。
问题是我在错误消息中只有原始的交换名称。我真正需要的是原始队列名称,因此我可以将消息重新发布到队列,而不是交换。
如何在错误消息中包含队列名称?
EasyNetQ_Default_Error_Queue中的示例错误消息:
{
"RoutingKey": "",
"Exchange": "EiHD.Application.Restaurant.Events.RestaurantDeliveryMailChanged:EiHD",
"Exception": "System.AggregateException: Um ou mais erros. ---> System.NullReferenceException: Referência de objeto não definida para uma instância de um objeto.\r\n em EiHD.Infrastructure.Mailing.EmailSender.OnEvent(RestaurantDeliveryMailChanged evt) na d:\\Projetos\\EatInHouseDelivery\\sln\\Infrastructure\\Mailing\\EmailSender.cs:linha 136\r\n em EiHD.Infrastructure.EventDispatching.EasyNeqQEventDispatcher.<>c__DisplayClass5`1.<RegisterListener>b__4(T evt) na d:\\Projetos\\EatInHouseDelivery\\sln\\Infrastructure\\EventDispatching\\EasyNeqQEventDispatcher.cs:linha 68\r\n em EasyNetQ.RabbitBus.<>c__DisplayClass6`1.<Subscribe>b__5(T msg)\r\n --- Fim do rastreamento de pilha de exceções internas ---\r\n---> (Exceção Interna N° 0) System.NullReferenceException: Referência de objeto não definida para uma instância de um objeto.\r\n em EiHD.Infrastructure.Mailing.EmailSender.OnEvent(RestaurantDeliveryMailChanged evt) na d:\\Projetos\\EatInHouseDelivery\\sln\\Infrastructure\\Mailing\\EmailSender.cs:linha 136\r\n em EiHD.Infrastructure.EventDispatching.EasyNeqQEventDispatcher.<>c__DisplayClass5`1.<RegisterListener>b__4(T evt) na d:\\Projetos\\EatInHouseDelivery\\sln\\Infrastructure\\EventDispatching\\EasyNeqQEventDispatcher.cs:linha 68\r\n em EasyNetQ.RabbitBus.<>c__DisplayClass6`1.<Subscribe>b__5(T msg)<---\r\n",
"Message": "{\"FromEmail\":\"someemail@gmail.com\",\"ToEmail\":\"anotheremail@gmail.com\",\"RestaurantName\":\"SomeRestaurant\"}",
"DateTime": "2015-10-25T19:20:17.2317949Z",
"BasicProperties": {
"ContentType": null,
"ContentEncoding": null,
"Headers": {},
"DeliveryMode": 2,
"Priority": 0,
"CorrelationId": "f212f734-6cd7-41fe-ac71-09335f44bb2c",
"ReplyTo": null,
"Expiration": null,
"MessageId": null,
"Timestamp": 0,
"Type": "EiHD.Application.Restaurant.Events.RestaurantDeliveryMailChanged:EiHD",
"UserId": null,
"AppId": null,
"ClusterId": null,
"ContentTypePresent": false,
"ContentEncodingPresent": false,
"HeadersPresent": true,
"DeliveryModePresent": true,
"PriorityPresent": false,
"CorrelationIdPresent": true,
"ReplyToPresent": false,
"ExpirationPresent": false,
"MessageIdPresent": false,
"TimestampPresent": false,
"TypePresent": true,
"UserIdPresent": false,
"AppIdPresent": false,
"ClusterIdPresent": false
}
}
答案 0 :(得分:1)
我想出了一个解决方案。
我必须将DefaultConsumerErrorStrategy类的扩展版本注册到我总线的IConsumerErrorStrategy:
this.bus = RabbitHutch.CreateBus(this.connectionString, (serviceRegister) => {
serviceRegister.Register<IConsumerErrorStrategy>((sp) => new ExtendedConsumerErrorStrategy(sp.Resolve<IConnectionFactory>(), sp.Resolve<ISerializer>(), sp.Resolve<IEasyNetQLogger>(), sp.Resolve<IConventions>(), sp.Resolve<ITypeNameSerializer>()));
});
public class ExtendedConsumerErrorStrategy : DefaultConsumerErrorStrategy
{
public ExtendedConsumerErrorStrategy(IConnectionFactory connectionFactory, ISerializer serializer, IEasyNetQLogger logger, IConventions conventions, ITypeNameSerializer typeNameSerializer)
: base(connectionFactory, serializer, logger, conventions, typeNameSerializer)
{
}
public override AckStrategy HandleConsumerError(ConsumerExecutionContext context, Exception exception)
{
context.Properties.Headers.Add("OriginalQueue", context.Info.Queue);
return base.HandleConsumerError(context, exception);
}
}
现在我的消息Headers属性中有原始队列名称。适合我。