3

This question is similar to others out there with answers, but I think things may have changed with AF v2 (I'm jumping into v2 without v1 experience). It seems that the assembly that AF v2 is integrated with for interacting with ServiceBus is Microsoft.Azure.ServiceBus, which has a class called "Message", which is not quite the same as "BrokeredMessage" found in other microsoft servicebus assemblies. One key difference between the two is that BrokeredMessage (which is referenced in almost all of the documentation, examples, and any other thread out there that I can find) has a .Deadletter() method on it, while Message does not. How can I deadletter a message intentionally when I don't have access to the Client or Receiver that received it?

(I have seen suggestions out there related to just cloning the message, putting on my own "dead letter" queue, and letting AF commit the original - I do not feel this is an adequate solution.)

Brandon
  • 173
  • 11
  • If you throw an exception and dont catch it, the function host will abandon the message. When the maxdeliverycount is reached, your message is pushed to the deadletter queue – Thomas Oct 24 '18 at 00:38
  • Yes, but there are "retryable" exceptions and "non-retryable" exceptions - I want to catch non-retryable and deadletter immediately, rather than waste resources retrying until maxdeliverycount is reached – Brandon Oct 24 '18 at 12:04
  • You can consider to catch the non-retryable once and move them to the poison queue through code. Poison queue usually gets created with following name "originalqueuename-poison". – Baskar Rao Oct 24 '18 at 13:40
  • yeah you do this you can't use the servicebustrigger – Thomas Oct 24 '18 at 18:41
  • @Baskar - I could be missing something, but it sounds like you are recommending creating my own "deadletter queue" - I indicated in my OP that this was not a desirable solution - let me know if I am missing something about your suggestion that differentiates it from this. – Brandon Oct 25 '18 at 13:14
  • @Thomas - do you have a thought about what would trigger the function then? – Brandon Oct 25 '18 at 13:16
  • @Brandon Since in your scenario you are already allowing Azure functions to create a poison queue for messages which needs to be retried , the poison queue will be of name "originalqueuename-poison". For those messages which you dont want to retry you can handle those messages in catch block and move them to the poison queue which functions has already created. – Baskar Rao Oct 25 '18 at 15:42
  • Having a time trigger function ? Or a plain old webjob ? Maybe you can do it using logic app, if it throws an exception you will be able to deadletter the message – Thomas Oct 25 '18 at 20:14

2 Answers2

5

I have yet to prove it out in the functions environment, but according to the ticket I opened on github (https://github.com/Azure/azure-webjobs-sdk/issues/1986), webjobs v3 supports binding both the Message and MessageReceiver that received it in the function trigger, and then the MessageReceiver can be used to deadletter the message.

Brandon
  • 173
  • 11
  • 1
    They really need to update the documentation, your answer is the only reference to this solution I've come across. I confirm that it works. – 0xFF Jan 29 '19 at 16:36
4

This was a real pain to find out as it's still not documented. The API reference on the Azure SDK for .NET project readme even points to the documentation from the old namespace ‍♂️

I had to search through the source code to find the correct way to get the LockToken.

    [FunctionName("MyFunction")]
    public static async Task Run([ServiceBusTrigger("myqueue", Connection = "myconnectionstring")] Message message,
        ILogger log, MessageReceiver messageReceiver)
    {
        await messageReceiver.DeadLetterAsync(message.SystemProperties.LockToken);
    }

Putting MessageReceiver as a parameter with automatically bind it, no additional set up needed.

Amicable
  • 3,115
  • 3
  • 49
  • 77
  • Besides this you should probably also disable autocomplete: https://stackoverflow.com/q/63179056/482758 – mkjeldsen Nov 29 '21 at 09:49