2

I am trying to port code that had been using Microsoft.WindowsAzure.Storage classes to use the newer classes in Azure.Data.Tables, Azure.Storage.Queues, etc. From what I have been able to discern, the StorageException class has been replaced by RequestFailedException. Unfortunately, there are some properties in StorageException that do not exist in RequestFailedException, making it difficult to log appropriate messages when an exception is encountered (for example: RequestId, RequestInformation, etc.).

The migration document does not address the differences between StorageException and the new RequestFailedException, or how to get error details from it.

It seems that either the new libraries are not yet mature enough for prime time, or maybe it is just because the documentation is lacking the relevant information and I can't find the appropriate methodologies for getting all of the error information from the RequestFailedException.

Does anyone know how to get more data out of the new class? Here are some examples of what we used to do:

catch (StorageException e)
{
    operation.Telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);

Changing the above to use RequestFailedException is a problem because RequestInformation is not a property of RequestFailedException.

Here is another case:

catch (StorageException se)
{
    var ri = se.RequestInformation;
    if (ri.ErrorCode == "TableNotFound")
    {
        Logger.Info(
            $"{SJResult.MakeInfo(64)} {ri.HttpStatusCode} {ri.HttpStatusMessage}, Storage Service code={ri.ErrorCode} This is OK if HL7 has not yet received messages."); // 60240040
    }
    else
    {
        Logger.Error(
            $"{SJResult.MakeError(65)} HttpStatusCode: {ri.HttpStatusCode}, HttpStatusMessage: {ri.HttpStatusMessage}, Storage Service code={ri.ErrorCode}, " +
            $"Extended.ErrorCode: {ri.ExtendedErrorInformation.ErrorCode} Extended.ErrorMessage: {ri.ExtendedErrorInformation.ErrorMessage}"); // E0240041 
        throw;
    }

Again, RequestInformation is not available in RequestFailedException.

How do we get access to all the detailed information (RequestInformation) about an exception from the new RequestFailedException class?

Dennis Jones
  • 211
  • 2
  • 13

1 Answers1

0

As you can see the definition of RequestFailedException Class (Azure) and constuctors in the latest version of azure sdk.

RequestFailedException(Int32, String, String, Exception) : gives HTTP status code ,specified error message, error code, and a reference to the inner exception .

And RequestFailedException(Response)
Gives error message, HTTP status code, error code obtained from the specified response.

The response in the argument represents the HTTP response from the service which has ClientRequestId as one of the properties as shown in the table which gets client request id that was sent to server in the form of x-ms-client-request-id headers.You can try the same while catching the error in the try-catch block.

enter image description here

In exception class you can give

public class RequestFailedException : Exception
{
...
    public RequestFailedException(int status, string message, string? errorCode, Exception? innerException)        : base(message , innerException) { }
}

Or use RequestFailedException(Response) from which you can get ClientRequestId.

I’ve not tested it myself, but please check if below can be worked around which is taken from the below references or check if something similar can give an idea.Also see if content property can be retrieved as a part of response.

try
{
  ...
      }
catch (Exception aex)
{
    foreach (var ex in aex.InnerExceptions)
    {
        if (ex is RequestFailedException except)
        {
        var innerException = excep.InnerException;
        if (innerException != null && innerException.GetType() == typeof(WebException))
        {
          WebException webEx = innerException as WebException;
          WebResponse resp = webEx.Response;
          var responseHeaders = resp.Headers;
          string requestId = responseHeaders["x-ms-request-id"];
          Console.WriteLine("Request Id: " + requestId);
            Console.WriteLine(except.InnerException.Message);
        }
        else
        {
            //  (not a RequestFailedException)
            Console.WriteLine($"{ex.Message}");
        }
    }

References:

  1. How can I get Request ID when an exception occurs? (microsoft.com)
  2. c# - How can you catch a RequestFailedException if making multiple DownloadToAsync calls in parallel? - Stack Overflow
kavyaS
  • 8,026
  • 1
  • 7
  • 19