public static DashErrorInformation Create(StorageExtendedErrorInformation src) { if (src != null) { return new DashErrorInformation { ErrorCode = src.ErrorCode, ErrorMessage = src.ErrorMessage, AdditionalDetails = src.AdditionalDetails, }; } return null; }
static StorageExtendedErrorInformation ReadFromStream(Stream inputStream) { StorageExtendedErrorInformation extendedErrorInfo = new StorageExtendedErrorInformation(); try { using (XmlReader reader = XmlReader.Create(inputStream)) { reader.Read(); extendedErrorInfo.ReadXml(reader); } return extendedErrorInfo; } catch (XmlException) { // If there is a parsing error we cannot return extended error information return null; } }
static StorageExtendedErrorInformation ReadFromStream(Stream inputStream) { StorageExtendedErrorInformation extendedErrorInfo = new StorageExtendedErrorInformation(); try { using (XmlReader reader = XmlReader.Create(inputStream)) { reader.Read(); extendedErrorInfo.ReadXml(reader); } return(extendedErrorInfo); } catch (XmlException) { // If there is a parsing error we cannot return extended error information return(null); } }
/// <summary> /// Parses the error details from the stream using OData library. /// </summary> /// <param name="responseMessage">The IODataResponseMessage to parse.</param> /// <returns>The error details.</returns> #if !WINDOWS_RT public static StorageExtendedErrorInformation ReadAndParseExtendedError(IODataResponseMessage responseMessage) { StorageExtendedErrorInformation storageExtendedError = null; using (ODataMessageReader reader = new ODataMessageReader(responseMessage)) { try { ODataError error = reader.ReadError(); if (error != null) { storageExtendedError = new StorageExtendedErrorInformation(); storageExtendedError.AdditionalDetails = new Dictionary <string, string>(); storageExtendedError.ErrorCode = error.ErrorCode; storageExtendedError.ErrorMessage = error.Message; if (error.InnerError != null) { storageExtendedError.AdditionalDetails[Constants.ErrorExceptionMessage] = error.InnerError.Message; storageExtendedError.AdditionalDetails[Constants.ErrorExceptionStackTrace] = error.InnerError.StackTrace; } #if !(WINDOWS_PHONE && WINDOWS_DESKTOP) if (error.InstanceAnnotations.Count > 0) { foreach (ODataInstanceAnnotation annotation in error.InstanceAnnotations) { storageExtendedError.AdditionalDetails[annotation.Name] = annotation.Value.GetAnnotation <string>(); } } #endif } } catch (Exception) { // Error cannot be parsed. return(null); } } return(storageExtendedError); }
/// <summary> /// Translates the specified exception into a storage exception. /// </summary> /// <param name="ex">The exception to translate.</param> /// <param name="reqResult">The request result.</param> /// <param name="parseError">The delegate used to parse the error to get extended error information.</param> /// <param name="responseStream">The error stream that contains the error information.</param> /// <returns>The storage exception.</returns> internal static StorageException TranslateExceptionWithPreBufferedStream(Exception ex, RequestResult reqResult, Func <Stream, StorageExtendedErrorInformation> parseError, Stream responseStream) { StorageException storageException; try { if ((storageException = CoreTranslate(ex, reqResult, ref parseError)) != null) { return(storageException); } #if !ASPNET_K WebException we = ex as WebException; if (we != null) { HttpWebResponse response = we.Response as HttpWebResponse; if (response != null) { PopulateRequestResult(reqResult, response); #if WINDOWS_RT reqResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(responseStream); #else reqResult.ExtendedErrorInformation = parseError(responseStream); #endif } } #endif } catch (Exception) { // if there is an error thrown while parsing the service error, just wrap the service error in a StorageException. // no op } // Just wrap in StorageException return(new StorageException(reqResult, ex.Message, ex)); }
public void ExtendedErrorInfoVerifyXml() { Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); CloudBlobContainer container = client.GetContainerReference(Guid.NewGuid().ToString("N")); try { StorageException e = TestHelper.ExpectedException <StorageException>( () => container.GetPermissions(), "Try to get permissions on a non-existent container"); Assert.IsNotNull(e.RequestInformation.ExtendedErrorInformation); StorageExtendedErrorInformation retrErrorInfo = new StorageExtendedErrorInformation(); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; StringBuilder sb = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(sb, settings)) { e.RequestInformation.ExtendedErrorInformation.WriteXml(writer); } using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) { retrErrorInfo.ReadXml(reader); } Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorCode, retrErrorInfo.ErrorCode); Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorMessage, retrErrorInfo.ErrorMessage); } finally { container.DeleteIfExists(); } }
static StorageExtendedErrorInformation ReadFromStream(Stream inputStream) { CommonUtility.AssertNotNull("inputStream", inputStream); if (inputStream.CanSeek && inputStream.Length < 1) { return null; } StorageExtendedErrorInformation extendedErrorInfo = new StorageExtendedErrorInformation(); try { using (XmlReader reader = XmlReader.Create(inputStream)) { reader.Read(); extendedErrorInfo.ReadXml(reader); } return extendedErrorInfo; } catch (XmlException) { // If there is a parsing error we cannot return extended error information return null; } }
/// <summary> /// Parses the error details from the stream using OData library. /// </summary> /// <param name="responseMessage">The IODataResponseMessage to parse.</param> /// <returns>The error details.</returns> public static StorageExtendedErrorInformation ReadAndParseExtendedError(IODataResponseMessage responseMessage) { StorageExtendedErrorInformation storageExtendedError = null; using (ODataMessageReader reader = new ODataMessageReader(responseMessage)) { try { ODataError error = reader.ReadError(); if (error != null) { storageExtendedError = new StorageExtendedErrorInformation(); storageExtendedError.AdditionalDetails = new Dictionary<string, string>(); storageExtendedError.ErrorCode = error.ErrorCode; storageExtendedError.ErrorMessage = error.Message; if (error.InnerError != null) { storageExtendedError.AdditionalDetails[Constants.ErrorExceptionMessage] = error.InnerError.Message; storageExtendedError.AdditionalDetails[Constants.ErrorExceptionStackTrace] = error.InnerError.StackTrace; } #if !(WINDOWS_PHONE && WINDOWS_DESKTOP) if (error.InstanceAnnotations.Count > 0) { foreach (ODataInstanceAnnotation annotation in error.InstanceAnnotations) { storageExtendedError.AdditionalDetails[annotation.Name] = annotation.Value.GetAnnotation<string>(); } } #endif } } catch (Exception) { // Error cannot be parsed. return null; } } return storageExtendedError; }
/// <summary> /// Translates the specified exception into a storage exception. /// </summary> /// <param name="ex">The exception to translate.</param> /// <param name="reqResult">The request result.</param> /// <returns>The storage exception.</returns> public static StorageException TranslateException(Exception ex, RequestResult reqResult) { // Dont re-wrap storage exceptions if (ex is StorageException) { return((StorageException)ex); } else if (ex is TimeoutException) { reqResult.HttpStatusMessage = null; reqResult.HttpStatusCode = (int)HttpStatusCode.Unused; reqResult.ExtendedErrorInformation = null; return(new StorageException(reqResult, ex.Message, ex)); } else if (ex is ArgumentException) { reqResult.HttpStatusMessage = null; reqResult.HttpStatusCode = (int)HttpStatusCode.Unused; reqResult.ExtendedErrorInformation = null; return(new StorageException(reqResult, ex.Message, ex) { IsRetryable = false }); } #if RT || XAMARIN else if (ex is OperationCanceledException) { reqResult.HttpStatusMessage = null; reqResult.HttpStatusCode = 306; // unused reqResult.ExtendedErrorInformation = null; return(new StorageException(reqResult, ex.Message, ex)); } #elif DNCP else { StorageException tableEx = TableUtilities.TranslateDataServiceClientException(ex, reqResult); if (tableEx != null) { return(tableEx); } } #endif WebException we = ex as WebException; if (we != null) { try { HttpWebResponse response = we.Response as HttpWebResponse; if (response != null) { reqResult.HttpStatusMessage = response.StatusDescription; reqResult.HttpStatusCode = (int)response.StatusCode; if (response.Headers != null) { #if DNCP reqResult.ServiceRequestID = HttpUtility.TryGetHeader(response, Constants.HeaderConstants.RequestIdHeader, null); reqResult.ContentMd5 = HttpUtility.TryGetHeader(response, "Content-MD5", null); string tempDate = HttpUtility.TryGetHeader(response, "Date", null); reqResult.RequestDate = string.IsNullOrEmpty(tempDate) ? DateTime.Now.ToString("R", CultureInfo.InvariantCulture) : tempDate; reqResult.Etag = response.Headers[HttpResponseHeader.ETag]; #endif } #if RT reqResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(response.GetResponseStream().AsInputStream()); #else reqResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(response.GetResponseStream()); #endif } } catch (Exception) { // no op } } // Not WebException, just wrap in StorageException return(new StorageException(reqResult, ex.Message, ex)); }
public void ExtendedErrorInfoVerifyXml() { Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); CloudBlobContainer container = client.GetContainerReference(Guid.NewGuid().ToString("N")); try { StorageException e = TestHelper.ExpectedException<StorageException>( () => container.GetPermissions(), "Try to get permissions on a non-existent container"); Assert.IsNotNull(e.RequestInformation.ExtendedErrorInformation); StorageExtendedErrorInformation retrErrorInfo = new StorageExtendedErrorInformation(); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; StringBuilder sb = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(sb, settings)) { e.RequestInformation.ExtendedErrorInformation.WriteXml(writer); } using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) { retrErrorInfo.ReadXml(reader); } Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorCode, retrErrorInfo.ErrorCode); Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorMessage, retrErrorInfo.ErrorMessage); } finally { container.DeleteIfExists(); } }
UnexpectedStorageResponseException(StorageExtendedErrorInformation error, string details) : base("Unexpected Table Storage response. Details: " + details) { Error = error; }
/// <summary> /// Translates the specified exception into a storage exception. /// </summary> /// <param name="ex">The exception to translate.</param> /// <param name="reqResult">The request result.</param> /// <param name="parseError">The delegate used to parse the error to get extended error information.</param> /// <param name="response">HTTP response message</param> /// <returns>The storage exception.</returns> public static StorageException TranslateException(Exception ex, RequestResult reqResult, Func <Stream, StorageExtendedErrorInformation> parseError, HttpResponseMessage response) { StorageException storageException; try { if ((storageException = CoreTranslate(ex, reqResult, ref parseError)) != null) { return(storageException); } if (response != null) { StorageException.PopulateRequestResult(reqResult, response); reqResult.ExtendedErrorInformation = CommonUtility.RunWithoutSynchronizationContext(() => StorageExtendedErrorInformation.ReadFromStream(response.Content.ReadAsStreamAsync().Result)); } } catch (Exception) { // if there is an error thrown while parsing the service error, just wrap the service error in a StorageException. // no op } // Just wrap in StorageException return(new StorageException(reqResult, ex.Message, ex)); }
internal static Exception UnableToParseTextBeforeSemicolonToInteger(StorageExtendedErrorInformation error) { return new UnexpectedStorageResponseException(error, "Unable to parse text on first line before semicolon as integer"); }
internal static Exception ErrorCodeShouldBeEntityAlreadyExists(StorageExtendedErrorInformation error) { return new UnexpectedStorageResponseException(error, "Erorr code should be indicated as 'EntityAlreadyExists' but was: " + error.ErrorCode); }
internal static Exception ConflictExceptionMessageShouldHaveSemicolonOnFirstLine(StorageExtendedErrorInformation error) { return new UnexpectedStorageResponseException(error, "Conflict exception message should have semicolon on first line"); }
internal static Exception ConflictExceptionMessageShouldHaveExactlyThreeLines(StorageExtendedErrorInformation error) { return new UnexpectedStorageResponseException(error, "Conflict exception message should have exactly 3 lines"); }
/// <summary> /// Parses the error details from the stream. /// </summary> /// <param name="responseStream">The stream to parse.</param> /// <param name="cancellationToken">Cancellation token used to cancel the request.</param> /// <returns>The error details.</returns> public static async Task <StorageExtendedErrorInformation> ReadAndParseExtendedErrorAsync(Stream responseStream, CancellationToken cancellationToken) { try { StreamReader streamReader = new StreamReader(responseStream); using (JsonReader reader = new JsonTextReader(streamReader)) { reader.DateParseHandling = DateParseHandling.None; JObject dataSet = await JObject.LoadAsync(reader, cancellationToken).ConfigureAwait(false); Dictionary <string, object> properties = dataSet.ToObject <Dictionary <string, object> >(DefaultSerializer.Create()); StorageExtendedErrorInformation errorInformation = new StorageExtendedErrorInformation(); errorInformation.AdditionalDetails = new Dictionary <string, string>(); if (properties.ContainsKey(@"odata.error")) { Dictionary <string, object> errorProperties = ((JObject)properties[@"odata.error"]).ToObject <Dictionary <string, object> >(DefaultSerializer.Create()); if (errorProperties.ContainsKey(@"code")) { #pragma warning disable 618 errorInformation.ErrorCode = (string)errorProperties[@"code"]; #pragma warning restore 618 } if (errorProperties.ContainsKey(@"message")) { Dictionary <string, object> errorMessageProperties = ((JObject)errorProperties[@"message"]).ToObject <Dictionary <string, object> >(DefaultSerializer.Create()); if (errorMessageProperties.ContainsKey(@"value")) { errorInformation.ErrorMessage = (string)errorMessageProperties[@"value"]; } } if (errorProperties.ContainsKey(@"innererror")) { Dictionary <string, object> innerErrorDictionary = ((JObject)errorProperties[@"innererror"]).ToObject <Dictionary <string, object> >(DefaultSerializer.Create()); if (innerErrorDictionary.ContainsKey(@"message")) { errorInformation.AdditionalDetails[Constants.ErrorExceptionMessage] = (string)innerErrorDictionary[@"message"]; } if (innerErrorDictionary.ContainsKey(@"type")) { errorInformation.AdditionalDetails[Constants.ErrorException] = (string)innerErrorDictionary[@"type"]; } if (innerErrorDictionary.ContainsKey(@"stacktrace")) { errorInformation.AdditionalDetails[Constants.ErrorExceptionStackTrace] = (string)innerErrorDictionary[@"stacktrace"]; } } } return(errorInformation); } } catch (Exception) { // Exception cannot be parsed, better to throw the original exception than the error-parsing exception. return(null); } }
public void ExtendedErrorInfoVerifyXmlWithAdditionalDetails() { Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); CloudBlobContainer container = client.GetContainerReference(Guid.NewGuid().ToString("N")); byte[] buffer = TestBase.GetRandomBuffer(4 * 1024 * 1024); MD5 md5 = MD5.Create(); string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); try { container.Create(); CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); List<string> blocks = new List<string>(); for (int i = 0; i < 2; i++) { blocks.Add(Convert.ToBase64String(Guid.NewGuid().ToByteArray())); } using (MemoryStream memoryStream = new MemoryStream(buffer)) { memoryStream.Seek(0, SeekOrigin.Begin); blob.PutBlock(blocks[0], memoryStream, contentMD5); int offset = buffer.Length - 1024; memoryStream.Seek(offset, SeekOrigin.Begin); StorageException e = TestHelper.ExpectedException<StorageException>( () => blob.PutBlock(blocks[1], memoryStream, contentMD5), "Invalid MD5 should fail with mismatch"); Assert.IsNotNull(e.RequestInformation.ExtendedErrorInformation); StorageExtendedErrorInformation retrErrorInfo = new StorageExtendedErrorInformation(); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; StringBuilder sb = new StringBuilder(); using (XmlWriter writer = XmlWriter.Create(sb, settings)) { e.RequestInformation.ExtendedErrorInformation.WriteXml(writer); } using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) { retrErrorInfo.ReadXml(reader); } Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorCode, retrErrorInfo.ErrorCode); Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorMessage, retrErrorInfo.ErrorMessage); Assert.AreNotEqual(0, retrErrorInfo.AdditionalDetails.Count); Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.AdditionalDetails.Count, retrErrorInfo.AdditionalDetails.Count); } } finally { container.DeleteIfExists(); } }