Exemple #1
0
        public static bool IsProblemTableDoesNotExist(this global::Azure.RequestFailedException exception)
        {
            return(exception.ParseExtendedErrorInformation(
                       (errorCode, message) =>
            {
                if (errorCode == ExtendedErrorInformationCodes.TableNotFound)
                {
                    return true;
                }
                if (errorCode == ExtendedErrorInformationCodes.BlobNotFound)
                {
                    return true;
                }
                return ExtendedErrorCodeNotProvided();
            },
                       () => ExtendedErrorCodeNotProvided()));

            bool ExtendedErrorCodeNotProvided()
            {
                if (exception.InnerException is System.Net.WebException)
                {
                    var webEx = (System.Net.WebException)exception.InnerException;

                    if (webEx.Response is System.Net.HttpWebResponse)
                    {
                        var httpResponse = (System.Net.HttpWebResponse)webEx.Response;
                        return(httpResponse.StatusCode == System.Net.HttpStatusCode.NotFound);
                    }
                }
                return(false);
            }
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="storageException"></param>
        /// <param name="onExtendedErrorInformation">Invoked with the RequestInformation.ExtendedErrorInformation. (ErrorCode and ErrorMessage, respectively) from the exception.</param>
        /// <param name="onExtendedErrorInformationNotProvided">Invoked when extended error information is not available</param>
        /// <returns></returns>
        public static TResult ParseExtendedErrorInformation <TResult>(this global::Azure.RequestFailedException storageException,
                                                                      Func <ExtendedErrorInformationCodes, string, TResult> onExtendedErrorInformation,
                                                                      Func <TResult> onExtendedErrorInformationNotProvided)
        {
            var errorCode    = storageException.ErrorCode;
            var errorMessage = storageException.Message.TryMatchRegex(
                "Status: (?<statusCode>[0-9]{3}) \\((?<message>.*)\\)",
                (statusCode, message) => statusCode.PairWithValue(message),
                out KeyValuePair <string, string> statusCodeMessageStr)?
                               statusCodeMessageStr.Value
                :
                               "Message could not be parsed";

            System.Diagnostics.Debug.WriteLine($"AST Error [{errorCode}]:{errorMessage})");

            var matchingCodes = Enum.GetNames(typeof(ExtendedErrorInformationCodes))
                                .Where(errorCodeName => String.Compare(errorCodeName, errorCode) == 0);

            if (!matchingCodes.Any())
            {
                return(onExtendedErrorInformation(ExtendedErrorInformationCodes.Other, errorMessage));
            }

            var matchingCodeString = matchingCodes.First();

            Enum.TryParse(matchingCodeString, out ExtendedErrorInformationCodes matchingCode);
            return(onExtendedErrorInformation(matchingCode, errorMessage));
        }
Exemple #3
0
        public static TResult ParseStorageException <TResult>(this global::Azure.RequestFailedException storageException,
                                                              Func <ExtendedErrorInformationCodes, string, TResult> onParsed,
                                                              Func <TResult> onUnableToParse)
        {
            return(storageException.ParseExtendedErrorInformation(
                       onParsed,
                       () =>
            {
                if (storageException.IsProblemTimeout())
                {
                    return onParsed(ExtendedErrorInformationCodes.Timeout, "The request to AST timed out.");
                }

                if (storageException.InnerException is System.Net.WebException)
                {
                    var webEx = storageException.InnerException as System.Net.WebException;
                    if (webEx.Response is System.Net.HttpWebResponse)
                    {
                        var httpWebResponse = webEx.Response as System.Net.HttpWebResponse;
                        try
                        {
                            var responseContent = webEx.Message;     // await httpWebResponse.GetResponseStream().ReadAsStringAsync();
                            System.Diagnostics.Debug.WriteLine($"AST replied:{responseContent}");
                            return onParsed(ExtendedErrorInformationCodes.General, responseContent);
                        }
                        catch (Exception exFromStream)
                        {
                            exFromStream.GetType();     // Suppress warning
                            return onUnableToParse();
                        }
                    }
                }
                return onUnableToParse();
            }));
        }
Exemple #4
0
        private static HttpStatusCode GetHttpStatusCode(this global::Azure.RequestFailedException storageException)
        {
            //if (storageException.Status)
            //    return HttpStatusCode.Ambiguous;

            return((HttpStatusCode)storageException.Status);
        }
Exemple #5
0
 public static bool IsProblemPreconditionFailed(this global::Azure.RequestFailedException exception)
 {
     if (exception.InnerException is System.Net.WebException)
     {
         var webEx = (System.Net.WebException)exception.InnerException;
         if (webEx.Response is System.Net.HttpWebResponse)
         {
             var httpResponse = (System.Net.HttpWebResponse)webEx.Response;
             return(httpResponse.StatusCode == System.Net.HttpStatusCode.PreconditionFailed);
         }
     }
     return(false);
 }
Exemple #6
0
        public static bool IsProblemTimeout(this global::Azure.RequestFailedException exception)
        {
            if (exception.InnerException is System.Net.WebException)
            {
                var webEx = (System.Net.WebException)exception.InnerException;
                return(webEx.Status == System.Net.WebExceptionStatus.Timeout);
            }
            if (408 == (int)exception.GetHttpStatusCode()) // RequestInformation.HttpStatusCode)
            {
                return(true);
            }

            return(false);
        }
Exemple #7
0
        public static bool IsProblemDoesNotExist(this global::Azure.RequestFailedException exception)
        {
            return(exception.ParseExtendedErrorInformation(
                       (errorCode, message) =>
            {
                if (errorCode == ExtendedErrorInformationCodes.TableNotFound)
                {
                    return true;
                }
                if (errorCode == ExtendedErrorInformationCodes.BlobNotFound)
                {
                    return true;
                }
                if (errorCode == ExtendedErrorInformationCodes.Other)
                {
                    if ("ContainerNotFound".Equals(exception.ErrorCode, StringComparison.OrdinalIgnoreCase))
                    {
                        return true;
                    }
                }
                return false;
            },
                       () =>
            {
                if (exception.GetHttpStatusCode() == HttpStatusCode.NotFound)
                {
                    return true;
                }
                if (exception.InnerException is System.Net.WebException)
                {
                    var webEx = (System.Net.WebException)exception.InnerException;

                    if (webEx.Response is System.Net.HttpWebResponse)
                    {
                        var httpResponse = (System.Net.HttpWebResponse)webEx.Response;
                        return (httpResponse.StatusCode == System.Net.HttpStatusCode.NotFound);
                    }
                }
                return false;
            }));
        }
Exemple #8
0
 public static bool IsProblemResourceAlreadyExists(this global::Azure.RequestFailedException exception)
 {
     return(exception.ParseExtendedErrorInformation(
                (errorCode, errorMessage) => errorCode == ExtendedErrorInformationCodes.EntityAlreadyExists,
                () => false));
 }
Exemple #9
0
 public static bool IsProblemPropertyValueTooLarge(this global::Azure.RequestFailedException exception)
 {
     return(exception.ParseExtendedErrorInformation(
                (errorCode, errorMessage) => errorCode == ExtendedErrorInformationCodes.PropertyValueTooLarge,
                () => false));
 }
Exemple #10
0
        public static TResult ParseStorageException <TResult>(this global::Azure.RequestFailedException storageException,
                                                              Func <string, TResult> onDuplicatePropertiesSpecified = default,
                                                              Func <string, TResult> onEntityAlreadyExists          = default,
                                                              Func <string, TResult> onEntityTooLarge        = default,
                                                              Func <string, TResult> onInvalidValueType      = default,
                                                              Func <string, TResult> onOutOfRangeInput       = default,
                                                              Func <string, TResult> onPropertiesNeedValue   = default,
                                                              Func <string, TResult> onPropertyNameInvalid   = default,
                                                              Func <string, TResult> onPropertyNameTooLong   = default,
                                                              Func <string, TResult> onPropertyValueTooLarge = default,
                                                              Func <string, TResult> onInvalidValueGeneral   = default,
                                                              Func <string, TResult> onTableAlreadyExists    = default,
                                                              Func <string, TResult> onTableBeingDeleted     = default,
                                                              Func <string, TResult> onNotFound                    = default,
                                                              Func <string, TResult> onTooManyProperties           = default,
                                                              Func <string, TResult> onUpdateConditionNotSatisfied = default,
                                                              Func <string, TResult> onTimeout = default,
                                                              Func <string, TResult> onOther   = default,
                                                              Func <string, TResult> onGeneral = default,
                                                              Func <ExtendedErrorInformationCodes, string, TResult> onDefaultCallback = default)
        {
            return(storageException.ParseStorageException(
                       (errorCode, msg) =>
            {
                switch (errorCode)
                {
                case ExtendedErrorInformationCodes.DuplicatePropertiesSpecified:
                    return ExecuteIfNotDefault(onDuplicatePropertiesSpecified);

                case ExtendedErrorInformationCodes.EntityAlreadyExists:
                    return ExecuteIfNotDefault(onEntityAlreadyExists);

                case ExtendedErrorInformationCodes.EntityTooLarge:
                    return ExecuteIfNotDefault(onEntityTooLarge);

                case ExtendedErrorInformationCodes.InvalidValueType:
                    return ExecuteIfNotDefault(onInvalidValueType);

                case ExtendedErrorInformationCodes.OutOfRangeInput:
                    return ExecuteIfNotDefault(onOutOfRangeInput);

                case ExtendedErrorInformationCodes.PropertiesNeedValue:
                    return ExecuteIfNotDefault(onPropertiesNeedValue);

                case ExtendedErrorInformationCodes.PropertyNameInvalid:
                    return ExecuteIfNotDefault(onPropertyNameInvalid);

                case ExtendedErrorInformationCodes.PropertyNameTooLong:
                    return ExecuteIfNotDefault(onPropertyNameTooLong);

                case ExtendedErrorInformationCodes.PropertyValueTooLarge:
                    return ExecuteIfNotDefault(onPropertyValueTooLarge);

                case ExtendedErrorInformationCodes.TableAlreadyExists:
                    return ExecuteIfNotDefault(onTableAlreadyExists);

                case ExtendedErrorInformationCodes.TableBeingDeleted:
                    return ExecuteIfNotDefault(onTableBeingDeleted);

                case ExtendedErrorInformationCodes.TableNotFound:
                case ExtendedErrorInformationCodes.BlobNotFound:
                    return ExecuteIfNotDefault(onNotFound);

                case ExtendedErrorInformationCodes.TooManyProperties:
                    return ExecuteIfNotDefault(onTooManyProperties);

                case ExtendedErrorInformationCodes.UpdateConditionNotSatisfied:
                    return ExecuteIfNotDefault(onUpdateConditionNotSatisfied);

                case ExtendedErrorInformationCodes.Timeout:
                    return ExecuteIfNotDefault(onTimeout);

                case ExtendedErrorInformationCodes.Other:
                    return ExecuteIfNotDefault(onOther);

                case ExtendedErrorInformationCodes.General:
                    return ExecuteIfNotDefault(onGeneral);

                case ExtendedErrorInformationCodes.InvalidValueGeneral:
                    return ExecuteIfNotDefault(onInvalidValueGeneral);
                }
                throw ExMsg($"case for {errorCode}");

                TResult ExecuteIfNotDefault(Func <string, TResult> func)
                {
                    if (!func.IsDefaultOrNull())
                    {
                        return func(msg);
                    }
                    if (!onDefaultCallback.IsDefaultOrNull())
                    {
                        return onDefaultCallback(errorCode, msg);
                    }
                    throw storageException;
                }
            },
                       () =>
            {
                if (storageException.InnerException.IsDefaultOrNull())
                {
                    throw ExHandleMsg("exceptions", storageException);
                }

                if (storageException.InnerException is System.Net.WebException)
                {
                    var webEx = (System.Net.WebException)storageException.InnerException;

                    if (webEx.Response is System.Net.HttpWebResponse)
                    {
                        var httpResponse = (System.Net.HttpWebResponse)webEx.Response;
                        var httpStatusCode = httpResponse.StatusCode;

                        if (httpStatusCode == HttpStatusCode.NotFound)
                        {
                            return onNotFound(webEx.Message);
                        }
                        if (httpStatusCode == HttpStatusCode.PreconditionFailed)
                        {
                            return onUpdateConditionNotSatisfied(webEx.Message);
                        }
                        if (httpStatusCode == HttpStatusCode.BadRequest)
                        {
                            return onInvalidValueGeneral(webEx.Message);
                        }
                        if (httpStatusCode == HttpStatusCode.RequestTimeout || httpStatusCode == HttpStatusCode.GatewayTimeout)
                        {
                            return onTimeout(webEx.Message);
                        }
                        throw ExHandleMsg("HttpResponse status code", httpStatusCode);
                    }
                    throw ExHandleMsg("inner exception response types", webEx.Response);
                }
                throw ExHandleMsg("inner exceptions", storageException.InnerException);

                Exception ExHandleMsg(string handle, object type)
                {
                    if (type.IsNull())
                    {
                        return new Exception($"{typeof(ResponseHandlingExtensions).FullName}.ParseStorageException `{handle}` -- Null Type");
                    }
                    if (type.GetType().IsEnum)
                    {
                        return ExMsg($"to handle {handle} of type {type}");
                    }
                    if (type.GetType() == typeof(string))
                    {
                        return ExMsg($"to handle {handle} of type {type}");
                    }
                    return ExHandleMsg(handle, type.GetType().FullName);
                }
            }));

            Exception ExMsg(string needMsg)
            {
                return(new Exception($"{typeof(ResponseHandlingExtensions).FullName}.ParseStorageException needs {needMsg}"));
            }
        }
Exemple #11
0
 public static Task <TResult> ResolveCreate <TResult>(this global::Azure.RequestFailedException exception,
                                                      CloudTable table,
                                                      Func <TResult> retry,
                                                      Func <ExtendedErrorInformationCodes, string, TResult> onFailure = default,
                                                      Func <TResult> onAlreadyExists             = default,
                                                      AzureStorageDriver.RetryDelegate onTimeout = default)
 {
     return(exception.ParseStorageException(
                onEntityAlreadyExists: (msg) =>
     {
         if (!onAlreadyExists.IsDefaultOrNull())
         {
             return onAlreadyExists().AsTask();
         }
         throw new ExtendedErrorInformationException(ExtendedErrorInformationCodes.EntityAlreadyExists, msg);
     },
                onNotFound: async(msg) => // IsProblemTableDoesNotExist
     {
         try
         {
             await table.CreateIfNotExistsAsync();
             return retry();
         }
         catch (global::Azure.RequestFailedException createEx)
         {
             // Catch bug with azure storage table client library where
             // if two resources attempt to create the table at the same
             // time one gets a precondtion failed error.
             System.Threading.Thread.Sleep(1000);
             return retry();
         }
         catch (Exception) { throw; };
     },
                onTimeout: async(msg) => // IsProblemTimeout
     {
         if (onTimeout.IsDefaultOrNull())
         {
             onTimeout = AzureStorageDriver.GetRetryDelegate();
         }
         bool shouldRetry = false;
         await onTimeout((int)exception.GetHttpStatusCode(), exception,
                         () =>
         {
             shouldRetry = true;
             return 1.AsTask();
         });
         if (shouldRetry)
         {
             return retry();
         }
         throw exception;
     },
                onDefaultCallback:
                (error, msg) =>
     {
         if (!onFailure.IsDefaultOrNull())
         {
             return onFailure(error, msg).AsTask();
         }
         throw new ExtendedErrorInformationException(error, msg);
     }));
 }