Date:

Share:

Handling Azure Service Bus errors with .NET

Related Articles

In this article, we are going to see what kind of errors you might get in Azure Service Bus and how to fix them. We will look for simpler errors, the ones you get if the configurations in your code are incorrect, or you have not declared the modules correctly; So let’s take a quick look at Dead letters And what they represent.

This is the last part in a series on the Azure Service Bus. In the previous sections we have seen

  1. Familiarity with Azure Service Bus
  2. Queues in front of topics
  3. Error handling

For this article, we are going to introduce some code errors that we used in the previous examples.

Just to sum up the context, our system receives orders for some pizzas through HTTP interfaces, processes them by adding some messages to the topic in the Azure Service Bus. Then, another app that listens to alerts on the subject, reads the message and performs some dummy actions.

Common Exceptions with the .NET SDK

To view the exceptions, we’d better keep the code we used in the previous examples handy.

Recall that a string has a shape like this:

string ConnectionString = "Endpoint=sb://<myHost>.servicebus.windows.net/;SharedAccessKeyName=<myPolicy>;SharedAccessKey=<myKey>=";

To send a message in a queue, remember that we have 3 main steps:

  1. Create new ServiceBusClient Show using the connection string
  2. Create new ServiceBusSender Specify the name of the queue or topic (in our case, the topic)
  3. Send the message by calling SendMessageAsync method
await using (ServiceBusClient client = new ServiceBusClient(ConnectionString))
{
    ServiceBusSender sender = client.CreateSender(TopicName);

    foreach (var order in validOrders)
    {
       
        
        ServiceBusMessage serializedContents = CreateServiceBusMessage(order);

        
        await sender.SendMessageAsync(serializedContents);
    }
}

To receive messages from a topic, we need the following steps:

  1. Create new ServiceBusClient Example as we did before
  2. Create new ServiceBusProcessor Show by specifying the name of the subject and the subscriber
  3. Set up an incoming message handler
  4. Set up an error handler
ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
ServiceBusProcessor _ordersProcessor = serviceBusClient.CreateProcessor(TopicName, SubscriptionName);
_ordersProcessor.ProcessMessageAsync += PizzaInvoiceMessageHandler;
_ordersProcessor.ProcessErrorAsync += PizzaItemErrorHandler;
await _ordersProcessor.StartProcessingAsync();

Of course, I recommend reading the previous articles to get a full understanding of the examples.

Now it’s time to post a few mistakes and see what happens.

No such host is known

When the connection string is invalid because the hostname is incorrect, you get Azure.Messaging.ServiceBus.ServiceBusException Exception with this post: No such host is known. Error code: HostNotFound.

What is the host? This is the first part of the connection string. For example, in a connection string like

Endpoint=sb://myHost.servicebus.windows.net/;SharedAccessKeyName=myPolicy;SharedAccessKey=myKey

The host is myHost.servicebus.net.

So we can easily understand why this error occurs: This host name does not exist (or, more likely, there is a typo).

Strange fact about this exception: He was thrown out later than I expected. I expected it to be thrown at boot ServiceBusClient Example, but is actually discarded only when a message is sent via SendMessageAsync.


You can perform all the actions you want without getting any error until you actually access the resources on the bus.

Failed to add token: The message entity X could not be found

Another message you may receive is Failed to add token. status-code: 404, status-description: The message entity ‘X’ was not found.

The reason is quite simple: the resource you are trying to use does not exist: by resource I mean queue, subject and subscription.

Again, this exception is only discarded when interacting directly with Azure Service Bus.

Failed to add token: The token has an invalid signature

If the connection string is invalid because it is invalid SharedAccessKeyName or SharedAccessKeyYou will get an exception of type System.UnauthorizedAccessException With the following message: Failed to add token. status-code: 401, status-description: InvalidSignature: The token has an invalid signature.

The best way to fix this is to go to the Azure portal and copy the credentials again, as I explained in the introductory article.

Processing cannot be started without setting up ProcessErrorAsync.

Let me recall a statement from my first article on Azure Service Bus:

However, at least PizzaItemErrorHandler should be declared, even if it is empty: you will get an exception if you forget about it.

This is strange, but it’s true: you need to set up therapists for both success and failure management.

If not, and you’re just declaring ProcessMessageAsync Therapist, as in this example:

ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
ServiceBusProcessor _ordersProcessor = serviceBusClient.CreateProcessor(TopicName, SubscriptionName);
_ordersProcessor.ProcessMessageAsync += PizzaInvoiceMessageHandler;

await _ordersProcessor.StartProcessingAsync();

You will receive an exception with the message: Processing cannot be started without setting up ProcessErrorAsync.


Exits exception when ProcessErrorAsync handler is not set

Therefore, the simplest way to resolve the error is to … create the handler for ProcessErrorAsync, Even empty. But why do we need it, then?

Why do we need the ProcessErrorAsync handler?

Like I said, yes, you can declare this therapist and leave it blank. But if it exists, there must be a reason, right?

The therapist has this signature:

private Task PizzaItemErrorHandler(ProcessErrorEventArgs arg)

And operates approx catch Shelter Block: All of the errors we threw away can be addressed in the first part of the article here. Of course, we do not directly accept a show of ExceptionBut we can access it by navigating arg resist.

As an example, let’s update the host part of the connection string again. When running the app, we can see that the error is perceived in PizzaItemErrorHandler The method, and the arg The argument contains many fields that we can use to fix an error. One of them is ExceptionWhich envelops the types of exceptions we have already seen.


Process Error Handling ProcessErrorAsync

This means that with this method you need to set up the handling of your errors, add logs, and anything that might help your application in error management.

The same handler can be used to manage errors that occur when performing actions on a message: If an exception is thrown while processing an incoming message, you have two options: handle it in ProcessMessageAsync Handles, in a try-catch block, or leave error handling in ProcessErrorAsync Therapist.


ProcessErrorEventArgs Details

In the image above, I marked an error while processing an incoming message by throwing a new message DivideByZeroException. As a result, e PizzaItemErrorHandler The method is called, and arg The argument contains information about the discarded exception.

I personally prefer to separate the two error handling modes: b ProcessMessageAsync Method I deal with errors that occur in business logic when acting on a message that has already been received; In the ProcessErrorAsync Method I handle errors that come from infrastructureSuch as connection string errors, invalid credentials and so on.

Dead letters: When messages become obsolete

When talking about queues, you will usually come across a term Dead letter. What it means?

Dead letters are unprocessed messages: Messages die When a message cannot be processed for a certain period of time. You can ignore this message because it is out of date or, in any case, cannot be processed – perhaps because it is corrupt.

Such messages are forwarded to a specific queue called Dead Letter Queue (DLQ): Messages are moved here to avoid creating the normal A queue full of messages that will never be processed.

You can see what messages exist in DLQ to try to figure out why they failed and put them back in the main queue.


Queue dead letters in ServiceBusExplorer

In the image above, you can see how to navigate DLQ using Service Bus Explorer: You can see all the messages in DLQ, update them (not just the content, but even the associated metadata), and put them back in line The main for processing.

Finishing

In this article we have seen some of the errors you may encounter while working with Azure Service Bus and .NET.

We have seen the most common exceptions, how to manage them on both the sending side and the receiving side: in the shelter you need to address them in ProcessErrorAsync Therapist.

Finally, we saw what a dead letter is and how messages transmitted to DLQ can be recovered.

This is the last part of this series on Azure Service Bus and .NET: There’s a lot more to talk about, like diving deeper into DLQ and understanding repeat experience patterns.

For more information, you can read This article on retry mechanisms in the .NET SDK Available in Microsoft Docs, and see This article By Felipe Polo Ruiz.

Happy coding! 🐧

.

Source

Popular Articles