Example #1
0
        /// <summary>
        /// Executes the entire message processing pipeline in an exception handler, tracking the number of failed delivery attempts.
        /// Forwards the message to the error queue when the max number of delivery attempts has been exceeded.
        /// </summary>
        public async Task Process(IncomingStepContext context, Func <Task> next)
        {
            var transportMessage   = context.Load <TransportMessage>() ?? throw new RebusApplicationException("Could not find a transport message in the current incoming step context");
            var transactionContext = context.Load <ITransactionContext>() ?? throw new RebusApplicationException("Could not find a transaction context in the current incoming step context");

            var messageId = transportMessage.Headers.GetValueOrNull(Headers.MessageId);

            if (string.IsNullOrWhiteSpace(messageId))
            {
                await _moveMessageToErrorQueue(context, transactionContext,
                                               new RebusApplicationException($"Received message with empty or absent '{Headers.MessageId}' header! All messages must be" +
                                                                             " supplied with an ID . If no ID is present, the message cannot be tracked" +
                                                                             " between delivery attempts, and other stuff would also be much harder to" +
                                                                             " do - therefore, it is a requirement that messages be supplied with an ID."));

                return;
            }

            _checkFinal(context, true);

            if (_errorTracker.HasFailedTooManyTimes(messageId))
            {
                await _handleError(context, next, messageId);
            }
            else
            {
                await _handle(context, next, messageId, transactionContext, messageId);
            }
        }
        /// <summary>
        /// Executes the entire message processing pipeline in an exception handler, tracking the number of failed delivery attempts.
        /// Forwards the message to the error queue when the max number of delivery attempts has been exceeded.
        /// </summary>
        public async Task Process(IncomingStepContext context, Func <Task> next)
        {
            var transportMessage   = context.Load <TransportMessage>();
            var transactionContext = context.Load <ITransactionContext>();
            var messageId          = transportMessage.Headers.GetValueOrNull(Headers.MessageId);

            if (string.IsNullOrWhiteSpace(messageId))
            {
                await MoveMessageToErrorQueue("<no message ID>", transportMessage,
                                              transactionContext, string.Format("Received message with empty or absent '{0}' header! All messages must be" +
                                                                                " supplied with an ID . If no ID is present, the message cannot be tracked" +
                                                                                " between delivery attempts, and other stuff would also be much harder to" +
                                                                                " do - therefore, it is a requirement that messages be supplied with an ID.",
                                                                                Headers.MessageId),
                                              shortErrorDescription : string.Format("Received message with empty or absent '{0}' header", Headers.MessageId));

                return;
            }

            if (_errorTracker.HasFailedTooManyTimes(messageId))
            {
                // if we don't have 2nd level retries, just get the message out of the way
                if (!_simpleRetryStrategySettings.SecondLevelRetriesEnabled)
                {
                    await
                    MoveMessageToErrorQueue(messageId, transportMessage, transactionContext,
                                            GetErrorDescriptionFor(messageId), GetErrorDescriptionFor(messageId, brief : true));

                    _errorTracker.CleanUp(messageId);
                    return;
                }

                // change the identifier to track by to perform this 2nd level of delivery attempts
                var secondLevelMessageId = messageId + "-2nd-level";

                if (_errorTracker.HasFailedTooManyTimes(secondLevelMessageId))
                {
                    await
                    MoveMessageToErrorQueue(messageId, transportMessage, transactionContext,
                                            GetErrorDescriptionFor(messageId), GetErrorDescriptionFor(messageId, brief : true));

                    _errorTracker.CleanUp(messageId);
                    _errorTracker.CleanUp(secondLevelMessageId);
                    return;
                }

                context.Save(DispatchAsFailedMessageKey, true);

                await DispatchWithTrackerIdentifier(next, secondLevelMessageId, transactionContext);

                return;
            }

            await DispatchWithTrackerIdentifier(next, messageId, transactionContext);
        }
Example #3
0
    /// <summary>
    /// Executes the entire message processing pipeline in an exception handler, tracking the number of failed delivery attempts.
    /// Forwards the message to the error queue when the max number of delivery attempts has been exceeded.
    /// </summary>
    public async Task Process(IncomingStepContext context, Func <Task> next)
    {
        var transportMessage   = context.Load <TransportMessage>() ?? throw new RebusApplicationException("Could not find a transport message in the current incoming step context");
        var transactionContext = context.Load <ITransactionContext>() ?? throw new RebusApplicationException("Could not find a transaction context in the current incoming step context");

        var messageId = transportMessage.Headers.GetValueOrNull(Headers.MessageId);

        if (string.IsNullOrWhiteSpace(messageId))
        {
            await MoveMessageToErrorQueue(context, transactionContext,
                                          new RebusApplicationException($"Received message with empty or absent '{Headers.MessageId}' header! All messages must be" +
                                                                        " supplied with an ID . If no ID is present, the message cannot be tracked" +
                                                                        " between delivery attempts, and other stuff would also be much harder to" +
                                                                        " do - therefore, it is a requirement that messages be supplied with an ID."));

            return;
        }

        if (_errorTracker.HasFailedTooManyTimes(messageId))
        {
            // if we don't have 2nd level retries, just get the message out of the way
            if (!_simpleRetryStrategySettings.SecondLevelRetriesEnabled)
            {
                var aggregateException = GetAggregateException(messageId);
                await MoveMessageToErrorQueue(context, transactionContext, aggregateException);

                _errorTracker.CleanUp(messageId);
                return;
            }

            // change the identifier to track by to perform this 2nd level of delivery attempts
            var secondLevelMessageId = GetSecondLevelMessageId(messageId);

            if (_errorTracker.HasFailedTooManyTimes(secondLevelMessageId))
            {
                var aggregateException = GetAggregateException(messageId, secondLevelMessageId);
                await MoveMessageToErrorQueue(context, transactionContext, aggregateException);

                _errorTracker.CleanUp(messageId);
                _errorTracker.CleanUp(secondLevelMessageId);
                return;
            }

            context.Save(DispatchAsFailedMessageKey, true);

            await DispatchWithTrackerIdentifier(next, secondLevelMessageId, transactionContext, messageId, secondLevelMessageId);

            return;
        }

        await DispatchWithTrackerIdentifier(next, messageId, transactionContext, messageId);
    }
        public async Task Process(IncomingStepContext context, Func <Task> next)
        {
            var    message   = context.Load <Message>();
            string messageId = message.GetMessageId();

            if (message.Body is ICommand command && !_errorTracker.HasFailedTooManyTimes(messageId))
            {
                var currentTransactionContext = context.Load <ITransactionContext>();
                var messagesCatcher           = currentTransactionContext.GetProvider().GetService <IMessagesCatcher>();
                if (!currentTransactionContext.GetIsAutoCompleteEventDisabled() &&
                    (messagesCatcher == null || !messagesCatcher.Messages.OfType <ICommandEvent>().Any()))
                {
                    object eventMessage = CreateEvent(command);
                    var    bus          = _serviceProvider.GetRequiredService <IBus>();
                    await bus.Publish(eventMessage);
                }
            }
            await next();
        }
 public bool HasFailedTooManyTimes(string messageId)
 {
     return(_innerErrorTracker.HasFailedTooManyTimes(messageId));
 }