As a developer I would like to be able to send a Service Bus message to the DeadLetter Queue and throw an Exception without triggering the automatic Abandon behavior when an Exception is thrown. This is because I want to surface errors in Application Insights by considering requests that results in a message being DeadLettered as a failed request. This occurs even when extensions.serviceBus.messageHandlerOptions.autoComplete is false.
Create an ServiceBusTrigger function like below:
[FunctionName("QueueTest")]
public static async Task QueueTest(
[ServiceBusTrigger("testqueue", Connection = "TestQueue")]string myQueueItem,
ILogger log,
MessageReceiver messageReceiver,
string lockToken
)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: '{myQueueItem}'");
await messageReceiver.DeadLetterAsync(lockToken, "DL");
log.LogInformation($"C# ServiceBus queue trigger function finished processing.");
throw new Exception("DL");
}
Add an item to the test queue and observe the behavior.
One exception thrown.
[3/21/2019 6:57:41 PM] Executed 'QueueTest' (Failed, Id=a76958d9-cefa-4d85-933e-178917709ef8)
[3/21/2019 6:57:41 PM] System.Private.CoreLib: Exception while executing function: QueueTest. QueueTestFunction: DL.
[3/21/2019 6:57:41 PM] MessageReceiver error (Action=UserCallback, ClientId=MessageReceiver1testqueue, EntityPath=testqueue, Endpoint=sonobello.servicebus.windows.net)
[3/21/2019 6:57:41 PM] System.Private.CoreLib: Exception while executing function: QueueTest. QueueTestFunction: DL.
Two exceptions are thrown.
[3/21/2019 6:57:41 PM] Executed 'QueueTest' (Failed, Id=a76958d9-cefa-4d85-933e-178917709ef8)
[3/21/2019 6:57:41 PM] System.Private.CoreLib: Exception while executing function: QueueTest. QueueTestFunction: DL.
[3/21/2019 6:57:41 PM] MessageReceiver error (Action=UserCallback, ClientId=MessageReceiver1testqueue, EntityPath=testqueue, Endpoint=sonobello.servicebus.windows.net)
[3/21/2019 6:57:41 PM] System.Private.CoreLib: Exception while executing function: QueueTest. QueueTestFunction: DL.
[3/21/2019 6:57:41 PM] MessageReceiver error (Action=Abandon, ClientId=MessageReceiver1testqueue, EntityPath=testqueue, Endpoint=sonobello.servicebus.windows.net)
[3/21/2019 6:57:41 PM] Microsoft.Azure.ServiceBus: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue, or was received by a different receiver instance.
You can not throw the Exception and DeadLetter the message. However, this will not log as a failure in Application Insights.
You can ignore the second Exception, but it is unwieldy and clutters the logs.
Microsoft.Azure.WebJobs.Extensions.ServiceBus 3.0.3
Microsoft.NET.Sdk.Functions 1.0.26
Related ticket regarding AutoAbandon #691
Hello everyone. I am working on exactly the same requirement. Do we have any progress on this?
Hello @alrod :)
Do you have any information on this?
Thanks.
Still seeing this issue, has anyone found the solution? I thought adding "autoComplete": true to the host.json would help, but doesn't seem to work for me
{
"version": "2.0",
"extensions": {
"serviceBus": {
"messageHandlerOptions": {
"autoComplete": true
}
}
}
}
I have the exact same problem. We have two requirements:
Everything I've read has told me the only way to have a function show as "Failed" is to throw an Exception at the end of it (which is kind of awful if you ask me) - forcing us to do the following:
```c#
[FunctionName("SomeSubscriberAsync")]
public async Task Run(ILogger logger, [ServiceBusTrigger("%ASubscriptionTopic%", "%ASubscription%", Connection = "AServiceBusConnectionString", IsSessionsEnabled = true)]Message message, MessageReceiver messageReceiver)
{
ReturnCode returnCode = await ProcessMessage(message, logger);
await ReleaseMessage(returnCode, message, messageReceiver, logger, "SomeSubscriber");
// See https://stackoverflow.com/questions/42782379 - the only way notify Azure of an error
// in the function app run is to raise an unhandled exception (even if it has been handled cleanly)
if(returnCode != ReturnCode.Success)
throw new Exception("Function execution failed - its all in the logs.");
}
This was supposed to be the method we use to put the message where we want it to go:
```c#
/// <summary>Based on how the message was handled, completes, abandons, or dead-letters it.</summary>
public static async Task ReleaseMessage(ReturnCode result, Message message, MessageReceiver messageReceiver, ILogger logger, string handlerName)
{
switch (result)
{
case ReturnCode.Success:
await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
logger.LogInformation($"{handlerName} has 'completed' the message {message.MessageId} due to successful handling.");
break;
case ReturnCode.TemporaryFailure:
await messageReceiver.AbandonAsync(message.SystemProperties.LockToken);
logger.LogWarning($"{handlerName} has 'abandoned' the message {message.MessageId} so that it can try again later.");
break;
case ReturnCode.PermanentFailure:
await messageReceiver.DeadLetterAsync(message.SystemProperties.LockToken);
logger.LogWarning($"{handlerName} has 'dead-lettered' the message {message.MessageId} due to a permanent failure.");
break;
}
}
But in the ticket description, some sort of auto-handling kicks in after the exception is thrown (despite my "sessionHandlerOptions": { "autoComplete": false) and I just get a huge error dump about the lock no longer being valid:
[7/22/2020 11:54:45 PM] SomeSubscriber has 'abandoned' the message 3bb4a192b65f4c8181d3dc23e6d76907 so that it can try again later.
[7/22/2020 11:55:12 PM] Executed 'SomeSubscriberAsync' (Failed, Id=cc035116-3384-4dc3-aac3-53afa9f8dc9d)
[7/22/2020 11:55:12 PM] System.Private.CoreLib: Exception while executing function: SomeSubscriberAsync. Functions: Function execution failed - its all in the logs.
[7/22/2020 11:55:12 PM] Message processing error (Action=UserCallback, ClientId=SubscriptionClient3aTopic/aSubscriber, EntityPath=aTopic/Subscriptions/aSubscriber, Endpoint=aservicebus.servicebus.windows.net)
[7/22/2020 11:55:12 PM] System.Private.CoreLib: Exception while executing function: SomeSubscriberAsync. Functions: Function execution failed - its all in the logs.
[7/22/2020 11:55:12 PM] Message processing error (Action=Abandon, ClientId=SubscriptionClient3aTopic/aSubscriber, EntityPath=aTopic/Subscriptions/aSubscriber, Endpoint=aservicebus.servicebus.windows.net)
[7/22/2020 11:55:12 PM] Microsoft.Azure.ServiceBus: The session lock has expired on the MessageSession. Accept a new MessageSession.
I even tried "Wait()ing" onCompleteAsync/DeadLetterAsync before throwing, but that doesn't help.
The only thing that prevents these red-herring errors from capping off every failed execution is to go back to not throwing an error, but that leaves me with no way to complete requirement #2 (which is to give any indication to the naked eye that an error occurred). In an ideal world, these requirements would not be mutually exclusive.
I'm currently hitting this issue as well (and I'm quite surprised since this issue exists for almost 2 years now!). The docs clearly state that when autoComplete: "false", we are responsible for handling abandon as well. So it's quite odd that the functions framework still abandons it on its own. Is there anyone responsible for fixing this?
Don't forget about that issue with using Startup: https://github.com/Azure/azure-functions-servicebus-extension/issues/81
Most helpful comment
Hello everyone. I am working on exactly the same requirement. Do we have any progress on this?