/// <summary>Initializes a new instance of the <see cref="StorageServerException"/> class.</summary> /// <param name="errorCode">The storage client error code. </param> /// <param name="message">The message that describes the exception. </param> /// <param name="statusCode">The HTTP status code returned in the response. </param> /// <param name="extendedErrorInfo">The extended error information. </param> /// <param name="innerException">The <see cref="Exception"/> instance that caused the current exception. </param> internal StorageServerException( StorageErrorCode errorCode, string message, HttpStatusCode statusCode, StorageExtendedErrorInformation extendedErrorInfo, Exception innerException) : base(errorCode, message, statusCode, extendedErrorInfo, innerException) { }
/// <summary>Initializes a new instance of the <see cref="StorageException"/> class.</summary> /// <param name="errorCode">The storage client error code. </param> /// <param name="message">The message that describes the exception. </param> /// <param name="statusCode">The HTTP status code returned in the response. </param> /// <param name="extendedErrorInfo">The extended error information. </param> /// <param name="innerException">The <see cref="Exception"/> instance that caused the current exception. </param> protected StorageException( StorageErrorCode errorCode, string message, HttpStatusCode statusCode, StorageExtendedErrorInformation extendedErrorInfo, Exception innerException) : base(message, innerException) { this.ErrorCode = errorCode; this.StatusCode = statusCode; this.ExtendedErrorInformation = extendedErrorInfo; }
/// <summary> /// Translates the extended error. /// </summary> /// <param name="details">The details.</param> /// <param name="statusCode">The status code.</param> /// <param name="statusDescription">The status description.</param> /// <param name="inner">The inner exception.</param> /// <returns>The translated exception.</returns> private static Exception TranslateExtendedError( StorageExtendedErrorInformation details, HttpStatusCode statusCode, string statusDescription, Exception inner) { StorageErrorCode errorCode = default(StorageErrorCode); switch (details.ErrorCode) { case StorageErrorCodeStrings.UnsupportedHttpVerb: case StorageErrorCodeStrings.MissingContentLengthHeader: case StorageErrorCodeStrings.MissingRequiredHeader: case StorageErrorCodeStrings.UnsupportedHeader: case StorageErrorCodeStrings.InvalidHeaderValue: case StorageErrorCodeStrings.MissingRequiredQueryParameter: case StorageErrorCodeStrings.UnsupportedQueryParameter: case StorageErrorCodeStrings.InvalidQueryParameterValue: case StorageErrorCodeStrings.OutOfRangeQueryParameterValue: case StorageErrorCodeStrings.InvalidUri: case StorageErrorCodeStrings.InvalidHttpVerb: case StorageErrorCodeStrings.EmptyMetadataKey: case StorageErrorCodeStrings.RequestBodyTooLarge: case StorageErrorCodeStrings.InvalidXmlDocument: case StorageErrorCodeStrings.InvalidXmlNodeValue: case StorageErrorCodeStrings.MissingRequiredXmlNode: case StorageErrorCodeStrings.InvalidMd5: case StorageErrorCodeStrings.OutOfRangeInput: case StorageErrorCodeStrings.InvalidInput: case StorageErrorCodeStrings.InvalidMetadata: case StorageErrorCodeStrings.MetadataTooLarge: case StorageErrorCodeStrings.InvalidRange: errorCode = StorageErrorCode.BadRequest; break; case StorageErrorCodeStrings.AuthenticationFailed: errorCode = StorageErrorCode.AuthenticationFailure; break; case StorageErrorCodeStrings.ResourceNotFound: errorCode = StorageErrorCode.ResourceNotFound; break; case StorageErrorCodeStrings.ConditionNotMet: errorCode = StorageErrorCode.ConditionFailed; break; case StorageErrorCodeStrings.ContainerAlreadyExists: errorCode = StorageErrorCode.ContainerAlreadyExists; break; case StorageErrorCodeStrings.ContainerNotFound: errorCode = StorageErrorCode.ContainerNotFound; break; case BlobErrorCodeStrings.BlobNotFound: errorCode = StorageErrorCode.BlobNotFound; break; case BlobErrorCodeStrings.BlobAlreadyExists: errorCode = StorageErrorCode.BlobAlreadyExists; break; } if (errorCode != default(StorageErrorCode)) { return(new StorageClientException( errorCode, statusDescription, statusCode, details, inner)); } switch (details.ErrorCode) { case StorageErrorCodeStrings.InternalError: case StorageErrorCodeStrings.ServerBusy: errorCode = StorageErrorCode.ServiceInternalError; break; case StorageErrorCodeStrings.Md5Mismatch: errorCode = StorageErrorCode.ServiceIntegrityCheckFailed; break; case StorageErrorCodeStrings.OperationTimedOut: errorCode = StorageErrorCode.ServiceTimeout; break; } if (errorCode != default(StorageErrorCode)) { return(new StorageServerException( errorCode, statusDescription, statusCode, details, inner)); } return(null); }
/// <summary> /// Translates the web exception. /// </summary> /// <param name="e">The exception.</param> /// <returns>The translated exception.</returns> internal static Exception TranslateWebException(Exception e) { WebException we = e as WebException; if (null == we) { return(e); } // If the response is not null, let's first see what the status code is. if (we.Response != null) { HttpWebResponse response = (HttpWebResponse)we.Response; StorageExtendedErrorInformation extendedError = GetExtendedErrorDetailsFromResponse( response.GetResponseStream(), response.ContentLength); Exception translatedException = null; if (extendedError != null) { translatedException = TranslateExtendedError( extendedError, response.StatusCode, response.StatusDescription, e); if (translatedException != null) { return(translatedException); } } translatedException = TranslateFromHttpStatus( response.StatusCode, response.StatusDescription, extendedError, we); if (translatedException != null) { return(translatedException); } } switch (we.Status) { case WebExceptionStatus.RequestCanceled: return(new StorageServerException( StorageErrorCode.ServiceTimeout, "The server request did not complete within the specified timeout", HttpStatusCode.GatewayTimeout, we)); case WebExceptionStatus.ConnectFailure: return(we); default: return(new StorageServerException( StorageErrorCode.ServiceInternalError, "The server encountered an unknown failure: " + e.Message, HttpStatusCode.InternalServerError, we)); } }
/// <summary> /// Translates from HTTP status. /// </summary> /// <param name="statusCode">The status code.</param> /// <param name="statusDescription">The status description.</param> /// <param name="details">The details.</param> /// <param name="inner">The inner.</param> /// <returns>The translated exception.</returns> internal static Exception TranslateFromHttpStatus( HttpStatusCode statusCode, string statusDescription, StorageExtendedErrorInformation details, Exception inner) { switch (statusCode) { case HttpStatusCode.Forbidden: return(new StorageClientException( StorageErrorCode.AccessDenied, statusDescription, HttpStatusCode.Forbidden, details, inner)); case HttpStatusCode.Gone: case HttpStatusCode.NotFound: return(new StorageClientException( StorageErrorCode.ResourceNotFound, statusDescription, statusCode, details, inner)); case HttpStatusCode.BadRequest: return(new StorageClientException( StorageErrorCode.BadRequest, statusDescription, statusCode, details, inner)); case HttpStatusCode.PreconditionFailed: case HttpStatusCode.NotModified: return(new StorageClientException( StorageErrorCode.ConditionFailed, statusDescription, statusCode, details, inner)); case HttpStatusCode.Conflict: return(new StorageClientException( StorageErrorCode.ResourceAlreadyExists, statusDescription, statusCode, details, inner)); case HttpStatusCode.GatewayTimeout: return(new StorageServerException( StorageErrorCode.ServiceTimeout, statusDescription, statusCode, details, inner)); case HttpStatusCode.RequestedRangeNotSatisfiable: return(new StorageClientException( StorageErrorCode.BadRequest, statusDescription, statusCode, details, inner)); case HttpStatusCode.InternalServerError: return(new StorageServerException( StorageErrorCode.ServiceInternalError, statusDescription, statusCode, details, inner)); case HttpStatusCode.NotImplemented: return(new StorageServerException( StorageErrorCode.NotImplemented, statusDescription, statusCode, details, inner)); case HttpStatusCode.BadGateway: return(new StorageServerException( StorageErrorCode.BadGateway, statusDescription, statusCode, details, inner)); case HttpStatusCode.HttpVersionNotSupported: return(new StorageServerException( StorageErrorCode.HttpVersionNotSupported, statusDescription, statusCode, details, inner)); } return(null); }
/// <summary>Translates the extended error.</summary> /// <param name="details">The details. </param> /// <param name="statusCode">The status code. </param> /// <param name="statusDescription">The status description. </param> /// <param name="inner">The inner exception. </param> /// <returns>The translated exception. </returns> private static Exception TranslateExtendedError( StorageExtendedErrorInformation details, HttpStatusCode statusCode, string statusDescription, Exception inner) { var errorCode = default(StorageErrorCode); switch (details.ErrorCode) { case StorageErrorCodeStrings.UnsupportedHttpVerb: case StorageErrorCodeStrings.MissingContentLengthHeader: case StorageErrorCodeStrings.MissingRequiredHeader: case StorageErrorCodeStrings.UnsupportedHeader: case StorageErrorCodeStrings.InvalidHeaderValue: case StorageErrorCodeStrings.MissingRequiredQueryParameter: case StorageErrorCodeStrings.UnsupportedQueryParameter: case StorageErrorCodeStrings.InvalidQueryParameterValue: case StorageErrorCodeStrings.OutOfRangeQueryParameterValue: case StorageErrorCodeStrings.InvalidUri: case StorageErrorCodeStrings.InvalidHttpVerb: case StorageErrorCodeStrings.EmptyMetadataKey: case StorageErrorCodeStrings.RequestBodyTooLarge: case StorageErrorCodeStrings.InvalidXmlDocument: case StorageErrorCodeStrings.InvalidXmlNodeValue: case StorageErrorCodeStrings.MissingRequiredXmlNode: case StorageErrorCodeStrings.InvalidMd5: case StorageErrorCodeStrings.OutOfRangeInput: case StorageErrorCodeStrings.InvalidInput: case StorageErrorCodeStrings.InvalidMetadata: case StorageErrorCodeStrings.MetadataTooLarge: case StorageErrorCodeStrings.InvalidRange: errorCode = StorageErrorCode.BadRequest; break; case StorageErrorCodeStrings.AuthenticationFailed: errorCode = StorageErrorCode.AuthenticationFailure; break; case StorageErrorCodeStrings.ResourceNotFound: errorCode = StorageErrorCode.ResourceNotFound; break; case StorageErrorCodeStrings.ConditionNotMet: errorCode = StorageErrorCode.ConditionFailed; break; case StorageErrorCodeStrings.ContainerAlreadyExists: errorCode = StorageErrorCode.ContainerAlreadyExists; break; case StorageErrorCodeStrings.ContainerNotFound: errorCode = StorageErrorCode.ContainerNotFound; break; case BlobErrorCodeStrings.BlobNotFound: errorCode = StorageErrorCode.BlobNotFound; break; case BlobErrorCodeStrings.BlobAlreadyExists: errorCode = StorageErrorCode.BlobAlreadyExists; break; } if (errorCode != default(StorageErrorCode)) { return new StorageClientException(errorCode, statusDescription, statusCode, details, inner); } switch (details.ErrorCode) { case StorageErrorCodeStrings.InternalError: case StorageErrorCodeStrings.ServerBusy: errorCode = StorageErrorCode.ServiceInternalError; break; case StorageErrorCodeStrings.Md5Mismatch: errorCode = StorageErrorCode.ServiceIntegrityCheckFailed; break; case StorageErrorCodeStrings.OperationTimedOut: errorCode = StorageErrorCode.ServiceTimeout; break; } if (errorCode != default(StorageErrorCode)) { return new StorageServerException(errorCode, statusDescription, statusCode, details, inner); } return null; }
/// <summary>Gets the error details from stream.</summary> /// <param name="inputStream">The input stream. </param> /// <returns>The error details. </returns> private static StorageExtendedErrorInformation GetErrorDetailsFromStream(Stream inputStream) { var extendedError = new StorageExtendedErrorInformation(); try { using (var reader = XmlReader.Create(inputStream)) { reader.Read(); reader.ReadStartElement(Constants.ErrorRootElement); extendedError.ErrorCode = reader.ReadElementString(Constants.ErrorCode); extendedError.ErrorMessage = reader.ReadElementString(Constants.ErrorMessage); extendedError.AdditionalDetails = new NameValueCollection(); // After error code and message we can have a number of additional details optionally followed // by ExceptionDetails element - we'll read all of these into the additionalDetails collection do { if (reader.IsStartElement()) { if (string.Compare(reader.LocalName, Constants.ErrorException, StringComparison.Ordinal) == 0) { // Need to read exception details - we have message and stack trace reader.ReadStartElement(Constants.ErrorException); extendedError.AdditionalDetails.Add( Constants.ErrorExceptionMessage, reader.ReadElementString(Constants.ErrorExceptionMessage)); extendedError.AdditionalDetails.Add( Constants.ErrorExceptionStackTrace, reader.ReadElementString(Constants.ErrorExceptionStackTrace)); reader.ReadEndElement(); } else { var elementName = reader.LocalName; extendedError.AdditionalDetails.Add(elementName, reader.ReadString()); } } } while (reader.Read()); } } catch (XmlException) { // If there is a parsing error we cannot return extended error information return null; } return extendedError; }
/// <summary>Translates from HTTP status.</summary> /// <param name="statusCode">The status code. </param> /// <param name="statusDescription">The status description. </param> /// <param name="details">The details. </param> /// <param name="inner">The inner. </param> /// <returns>The translated exception. </returns> internal static Exception TranslateFromHttpStatus( HttpStatusCode statusCode, string statusDescription, StorageExtendedErrorInformation details, Exception inner) { switch (statusCode) { case HttpStatusCode.Forbidden: return new StorageClientException( StorageErrorCode.AccessDenied, statusDescription, HttpStatusCode.Forbidden, details, inner); case HttpStatusCode.Gone: case HttpStatusCode.NotFound: return new StorageClientException( StorageErrorCode.ResourceNotFound, statusDescription, statusCode, details, inner); case HttpStatusCode.BadRequest: return new StorageClientException( StorageErrorCode.BadRequest, statusDescription, statusCode, details, inner); case HttpStatusCode.PreconditionFailed: case HttpStatusCode.NotModified: return new StorageClientException( StorageErrorCode.ConditionFailed, statusDescription, statusCode, details, inner); case HttpStatusCode.Conflict: return new StorageClientException( StorageErrorCode.ResourceAlreadyExists, statusDescription, statusCode, details, inner); case HttpStatusCode.GatewayTimeout: return new StorageServerException( StorageErrorCode.ServiceTimeout, statusDescription, statusCode, details, inner); case HttpStatusCode.RequestedRangeNotSatisfiable: return new StorageClientException( StorageErrorCode.BadRequest, statusDescription, statusCode, details, inner); case HttpStatusCode.InternalServerError: return new StorageServerException( StorageErrorCode.ServiceInternalError, statusDescription, statusCode, details, inner); case HttpStatusCode.NotImplemented: return new StorageServerException( StorageErrorCode.NotImplemented, statusDescription, statusCode, details, inner); case HttpStatusCode.BadGateway: return new StorageServerException( StorageErrorCode.BadGateway, statusDescription, statusCode, details, inner); case HttpStatusCode.HttpVersionNotSupported: return new StorageServerException( StorageErrorCode.HttpVersionNotSupported, statusDescription, statusCode, details, inner); } return null; }
/// <summary>Gets the extended error from XML message.</summary> /// <param name="xmlErrorMessage">The XML error message. </param> /// <returns>The extended error information. </returns> internal static StorageExtendedErrorInformation GetExtendedErrorFromXmlMessage(string xmlErrorMessage) { string message = null; string errorCode; var errorCodeName = XName.Get(Constants.TableErrorCodeElement, Constants.DataWebMetadataNamespace); var messageName = XName.Get(Constants.TableErrorMessageElement, Constants.DataWebMetadataNamespace); using (var reader = new StringReader(xmlErrorMessage)) { XDocument xDocument; try { xDocument = XDocument.Load(reader); } catch (XmlException) { // The XML could not be parsed. This could happen either because the connection // could not be made to the server, or if the response did not contain the // error details (for example, if the response status code was neither a failure // nor a success, but a 3XX code such as NotModified. return null; } var errorCodeElement = xDocument.Descendants(errorCodeName).FirstOrDefault(); if (errorCodeElement == null) { return null; } errorCode = errorCodeElement.Value; var messageElement = xDocument.Descendants(messageName).FirstOrDefault(); if (messageElement != null) { message = messageElement.Value; } } var errorDetails = new StorageExtendedErrorInformation { ErrorMessage = message, ErrorCode = errorCode }; return errorDetails; }