rama creada apartir de master en j
This commit is contained in:
@@ -8,34 +8,45 @@ using ILogger = Serilog.ILogger;
|
||||
|
||||
namespace adas_core.Infrastructure.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// Handles errors that occur during RabbitMQ message consumption and publishes them using the configured publisher service.
|
||||
/// </summary>
|
||||
public class RabbitConsumerErrorHandler(IPublisherService publisherService)
|
||||
{
|
||||
private const int MaxRetries = 2;
|
||||
private static readonly ILogger Logger = Log.ForContext<RabbitConsumerErrorHandler>();
|
||||
|
||||
/// <summary>
|
||||
/// Processes a received message by invoking the next handler in the pipeline, and on failure logs the error,
|
||||
/// serializes the message body to a string, and delegates to the retry handler using the message properties,
|
||||
/// received info, and the captured exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The deserialized message whose body is inspected or re-serialized for retry handling.</param>
|
||||
/// <param name="receivedInfo">Information about the message receipt, passed to the retry handler.</param>
|
||||
/// <param name="next">The asynchronous delegate representing the next step in the processing pipeline.</param>
|
||||
public async Task HandleAsync<T>(
|
||||
Message<T> message,
|
||||
MessageReceivedInfo receivedInfo,
|
||||
Func<Task> next)
|
||||
{
|
||||
try
|
||||
Message<T> message,
|
||||
MessageReceivedInfo receivedInfo,
|
||||
Func<Task> next)
|
||||
{
|
||||
await next();
|
||||
try
|
||||
{
|
||||
await next();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logger.Error(exception, "Consumer error {Message}", exception.Message);
|
||||
|
||||
var properties = message.Properties;
|
||||
|
||||
var body = Encoding.UTF8.GetString(
|
||||
message.Body is byte[] bytes
|
||||
? bytes
|
||||
: Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message.Body)));
|
||||
|
||||
HandleRetries(receivedInfo, properties, body, exception);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logger.Error(exception, "Consumer error {Message}", exception.Message);
|
||||
|
||||
var properties = message.Properties;
|
||||
|
||||
var body = Encoding.UTF8.GetString(
|
||||
message.Body is byte[] bytes
|
||||
? bytes
|
||||
: Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message.Body)));
|
||||
|
||||
HandleRetries(receivedInfo, properties, body, exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRetries(
|
||||
MessageReceivedInfo receivedInfo,
|
||||
@@ -102,44 +113,58 @@ public class RabbitConsumerErrorHandler(IPublisherService publisherService)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the retry count from the message properties headers. Returns the deserialized integer value when a "retries" header containing a byte array is present, or 0 when the headers are missing, the key is not found, or the value is not a byte array.
|
||||
/// </summary>
|
||||
/// <param name="properties">The message properties whose headers are inspected for the "retries" entry.</param>
|
||||
/// <returns>The number of retries parsed from the "retries" header, or 0 if the header is absent or not a byte array.</returns>
|
||||
private int GetRetries(MessageProperties properties)
|
||||
{
|
||||
if (properties.Headers != null &&
|
||||
properties.Headers.TryGetValue("retries", out var retriesObj) &&
|
||||
retriesObj is byte[] bytes)
|
||||
{
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
if (properties.Headers != null &&
|
||||
properties.Headers.TryGetValue("retries", out var retriesObj) &&
|
||||
retriesObj is byte[] bytes)
|
||||
{
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new error message that preserves the original message properties and attaches exception details for downstream processing or dead-letter handling.
|
||||
/// </summary>
|
||||
/// <param name="receivedInfo">The metadata of the original received message, including exchange, routing key, and queue information used to identify the error source.</param>
|
||||
/// <param name="originalProperties">The properties of the original message from which delivery mode, content type, correlation id, and message id are copied.</param>
|
||||
/// <param name="body">The raw body of the original message that caused the error.</param>
|
||||
/// <param name="exception">The exception that was raised, whose message is included in the error payload.</param>
|
||||
/// <param name="headers">The headers to associate with the resulting error message.</param>
|
||||
/// <returns>A <see cref="Message{Error}"/> containing the constructed error and the propagated message properties.</returns>
|
||||
private static Message<Error> CreateErrorMessage(
|
||||
MessageReceivedInfo receivedInfo,
|
||||
MessageProperties originalProperties,
|
||||
string body,
|
||||
Exception exception,
|
||||
Dictionary<string, object> headers)
|
||||
{
|
||||
var props = new MessageProperties
|
||||
MessageReceivedInfo receivedInfo,
|
||||
MessageProperties originalProperties,
|
||||
string body,
|
||||
Exception exception,
|
||||
Dictionary<string, object> headers)
|
||||
{
|
||||
Headers = headers,
|
||||
DeliveryMode = originalProperties.DeliveryMode,
|
||||
ContentType = originalProperties.ContentType,
|
||||
CorrelationId = originalProperties.CorrelationId,
|
||||
MessageId = originalProperties.MessageId
|
||||
};
|
||||
|
||||
var error = new Error(
|
||||
body,
|
||||
exception.Message,
|
||||
receivedInfo.Exchange,
|
||||
receivedInfo.RoutingKey,
|
||||
receivedInfo.Queue,
|
||||
DateTime.UtcNow,
|
||||
props
|
||||
);
|
||||
|
||||
return new Message<Error>(error, props);
|
||||
}
|
||||
var props = new MessageProperties
|
||||
{
|
||||
Headers = headers,
|
||||
DeliveryMode = originalProperties.DeliveryMode,
|
||||
ContentType = originalProperties.ContentType,
|
||||
CorrelationId = originalProperties.CorrelationId,
|
||||
MessageId = originalProperties.MessageId
|
||||
};
|
||||
|
||||
var error = new Error(
|
||||
body,
|
||||
exception.Message,
|
||||
receivedInfo.Exchange,
|
||||
receivedInfo.RoutingKey,
|
||||
receivedInfo.Queue,
|
||||
DateTime.UtcNow,
|
||||
props
|
||||
);
|
||||
|
||||
return new Message<Error>(error, props);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user