public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { try { var message = handlingContext.Error.Message; var destination = message.Headers["ServiceControl.TargetEndpointAddress"]; var messageUniqueId = message.Headers["ServiceControl.Retry.UniqueMessageId"]; Log.Warn($"Failed to send '{messageUniqueId}' message to '{destination}' for retry. Attempting to revert message status to unresolved so it can be tried again.", handlingContext.Error.Exception); using (var session = store.OpenAsyncSession()) { var failedMessage = await session.LoadAsync <FailedMessage>(FailedMessage.MakeDocumentId(messageUniqueId)) .ConfigureAwait(false); if (failedMessage != null) { failedMessage.Status = FailedMessageStatus.Unresolved; } var failedMessageRetry = await session.LoadAsync <FailedMessageRetry>(FailedMessageRetry.MakeDocumentId(messageUniqueId)) .ConfigureAwait(false); if (failedMessageRetry != null) { session.Delete(failedMessageRetry); } await session.SaveChangesAsync() .ConfigureAwait(false); } string reason; try { reason = handlingContext.Error.Exception.GetBaseException().Message; } catch (Exception) { reason = "Failed to retrieve reason!"; } await domainEvents.Raise(new MessagesSubmittedForRetryFailed { Reason = reason, FailedMessageId = messageUniqueId, Destination = destination }).ConfigureAwait(false); } catch (Exception ex) { // If something goes wrong here we just ignore, not the end of the world! Log.Error("A failure occurred when trying to handle a retry failure.", ex); } finally { executeOnFailure(); } return(ErrorHandleResult.Handled); }
/// <summary> /// Invoked when an error occurs while processing a message. /// </summary> /// <param name="handlingContext">Error handling context.</param> /// <param name="dispatcher">Dispatcher.</param> public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { var message = handlingContext.Error.Message; if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries) { return(ErrorHandleResult.RetryRequired); } string delayedRetryHeader; if (message.Headers.TryGetValue("NServiceBus.Raw.DelayedRetries.Attempt", out delayedRetryHeader)) { var attempt = int.Parse(delayedRetryHeader); if (attempt >= delayedRetries) { await handlingContext.MoveToErrorQueue(errorQueue).ConfigureAwait(false); return(ErrorHandleResult.Handled); } } message.Headers["NServiceBus.Raw.DelayedRetries.Due"] = (DateTime.UtcNow + delay).ToString("O"); message.Headers["NServiceBus.Raw.DelayedRetries.RetryTo"] = handlingContext.FailedQueue; var delayedMessage = new OutgoingMessage(message.MessageId, message.Headers, message.Body); var operation = new TransportOperation(delayedMessage, new UnicastAddressTag(delayQueue)); await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag()) .ConfigureAwait(false); return(ErrorHandleResult.Handled); }
public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries) { return(ErrorHandleResult.RetryRequired); } if (handlingContext.Error.DelayedDeliveriesPerformed >= delayedRetries) { //More than five times this message triggered throttled mode -> poison return(await poisonMessageHandling(handlingContext, dispatcher).ConfigureAwait(false)); } //Move to back of the queue. var incomingMessage = handlingContext.Error.Message; var message = new OutgoingMessage(incomingMessage.MessageId, incomingMessage.Headers, incomingMessage.Body); var operation = new TransportOperation(message, new UnicastAddressTag(inputQueue)); //Only increment the delayed retries count if CB was not armed. That means that at least one message was //successfully forwarded in between previous failure of this message and this failure. //This prevents prematurely exhausting delayed retries attempts without triggering the throttled mode if (!circuitBreaker.IsArmed) { var newDelayedRetriesHeaderValue = handlingContext.Error.DelayedDeliveriesPerformed + 1; incomingMessage.Headers[Headers.DelayedRetries] = newDelayedRetriesHeaderValue.ToString(); } await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag()) .ConfigureAwait(false); //Notify the circuit breaker await circuitBreaker.Failure(handlingContext.Error.Exception).ConfigureAwait(false); return(ErrorHandleResult.Handled); }
public Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { if (handlingContext.Error.ImmediateProcessingFailures < immediateRetryCount) { return(Task.FromResult(ErrorHandleResult.RetryRequired)); } return(handlingContext.MoveToErrorQueue(errorQueue)); }
public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { //Same as recoverability policy in NServiceBusFactory if (handlingContext.Error.ImmediateProcessingFailures < 3) { return(ErrorHandleResult.RetryRequired); } await importFailuresHandler.Handle(handlingContext.Error) .ConfigureAwait(false); return(ErrorHandleResult.Handled); }
public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { //Same as recoverability policy in NServiceBusFactory if (handlingContext.Error.ImmediateProcessingFailures < 3) { return(ErrorHandleResult.RetryRequired); } await StoreFailedMessageDocument(handlingContext.Error) .ConfigureAwait(false); await handlingContext.MoveToErrorQueue(handlingContext.FailedQueue, false) .ConfigureAwait(false); return(ErrorHandleResult.Handled); }
public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { await Task.Delay(1000); if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries) { return(ErrorHandleResult.RetryRequired); } logger.Error("Error processing a message. Continuing in throttled mode.", handlingContext.Error.Exception); //Move to back of the queue. var incomingMessage = handlingContext.Error.Message; var message = new OutgoingMessage(incomingMessage.MessageId, incomingMessage.Headers, incomingMessage.Body); var operation = new TransportOperation(message, new UnicastAddressTag(inputQueue)); await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag()) .ConfigureAwait(false); return(ErrorHandleResult.Handled); }
public Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher) { return(Task.FromResult(ErrorHandleResult.Handled)); }