azure-storage-net: ExtendedErrorInformation is null when HTTP body is present

Recently, ExtendedErrorInformation on StorageException started being null some of the time when it should not be. This is using SDK version 4.3.0, but I believe the code is unchanged in the latest. (Let me know if that’s not the case.)

The following code (simplified repro) should work, but sometimes does not:

try
{
    blob.Delete();
}
catch (StorageException ex)
{
    if (ex.RequestInformation.ExtendedErrorInformation != null && ex.RequestInformation.ExtendedErrorInformation.ErrorCode = "BlobNotFound")
    {
         // Expected possibility; continue
    }
    else
    {
        throw;
    }
}

The code above usually continues but recently started throwing when it should not. Examining the exception, the ExtendedErrorInformation returns null. But when viewing the inner exception, I’m able to get valid ExtendedErrorInformation back. Using the following code:

StorageExtendedErrorInformation extendedInformation = ex.RequestInformation.ExtendedErrorInformation;

if (extendedInformation == null)
{
    Console.WriteLine("Null extended information");
}
else
{
    Console.WriteLine("ErrorCode: {0}", extendedInformation.ErrorCode);
    Console.WriteLine("ErrorMessage: {0}", extendedInformation.ErrorMessage);
}

WebException webException = (WebException)ex.InnerException;
HttpWebResponse response = (HttpWebResponse)webException.Response;
MemoryStream s = (MemoryStream)response.GetResponseStream();
MemoryStream s2 = new MemoryStream(s.GetBuffer(), 0, (int)response.ContentLength);
TextReader r = new StreamReader(s2);
Console.WriteLine(r.ReadToEnd());
s2.Position = 0;
extendedInformation = StorageExtendedErrorInformation.ReadFromStream(s2);

if (extendedInformation == null)
{
    Console.WriteLine("Null extended information");
}
else
{
    Console.WriteLine("ErrorCode: {0}", extendedInformation.ErrorCode);
    Console.WriteLine("ErrorMessage: {0}", extendedInformation.ErrorMessage);
}

it outputs:

Null extended information Content: <?xml version="1.0" encoding="utf-8"?><Error>BlobNotFound<Message>The specified blob does not exist. RequestId:37af06c8-0001-0106-4fd0-a4815b000000 Time:2016-05-03T00:12:08.3285784Z</Message></Error> ErrorCode: BlobNotFound ErrorMessage: The specified blob does not exist. RequestId:37af06c8-0001-0106-4fd0-a4815b000000 Time:2016-05-03T00:12:08.3285784Z

In other words, the HTTP Response message actually has an XML body that contains the extended error information in a valid format that can be used if the response buffer stream is accessed directly, but when StorageException is constructed, the ExtendedErrorInformation is set to null.

Note that this problem does not occur on every attempt, on some, so I suspect there’s something in the interaction between StorageException and HttpWebResponse’s stream that is causing the problem.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 15 (7 by maintainers)

Most upvoted comments

We fixed this in version 8.0 of our library. Now the behavior doesn’t happen in blob/file/queue services and we throw if the dependency is missing where it’s truly needed in table service.

What I think you’re asking for is an assembly load exception rather than silently failing to populate extended error info. This is in effect the work we are tracking, except tweaked to make the breaking change significantly less severe for users who happen to be running without some dependencies today.

The general case of detecting a bad environment is trickier. In .NET, dependencies are loaded dynamically as needed so it’s not practical to fail fast in the presence of a corrupt environment. You will get apparently working behavior until the DLL load is attempted. Also note that environment corruption is not something a library can fully handle itself. You will need to ensure integrity of your deployment.

I am fine with tracking it as a bug. I’m reopening this issue for tracking.