When it receives the messages it marks them as complete and they are no longer in the queue.
By default, the Functions runtime actually doesn't mark a message as complete until your function returns successfully. As mentioned in the accepted answer, throwing an exception (in your case, if the API being called returns with an unfavorable response) would abandon the message and prevent it from being marked as complete.
For a lot more control over when your message is completed, abandoned, etc, you can consume your message as a BrokeredMessage type as mentioned previously. This class directly supports the methods you'd need to control what happens to your message. Note, the service bus trigger documentation mentions that BrokeredMessage
should be used for Azure Functions version 1.*. If you're using version 2.*, you should consume your message as a Message type instead.
One pain-point of using Message
is that, unlike BrokeredMessage
, it doesn't directly have methods to let you control when a message is completed, etc. To achieve this, we can bind a MessageReceiver parameter to our function.
To show how this works, here's an dead-lettering example of using Message
along with MessageReceiver
:
[FunctionName("SOExampleFunction"]
public static async Task ProcessMessage(
[ServiceBusTrigger("myqueue")] Message message,
MessageReceiver messageReceiver)
{
. . .
await messageReceiver.DeadLetterAsync(message.SystemProperties.LockToken);
. . .
}
While using this approach, make sure you have the "autoComplete" service bus setting set to false in your host.json. E.g.:
{
"version": "2.0",
"extensions": {
"serviceBus": {
"messageHandlerOptions": {
"autoComplete": false
}
}
}
}