/// <summary>
        /// Removes a mapping.
        /// </summary>
        /// <param name="statusCode">The status code.</param>
        /// <param name="errorCode">The error code.</param>
        public void RemoveMapping(HttpStatusCode statusCode, string errorCode)
        {
            var registration = new ErrorRegistration(statusCode, errorCode);

            if (!this.mappings.ContainsKey(registration))
            {
                throw new InvalidOperationException(
                          $"HTTP response to exception mapping is not registered for response status code {statusCode} and error code {errorCode}");
            }

            this.mappings.Remove(registration);
        }
        /// <summary>
        /// Updates a mapping.
        /// </summary>
        /// <param name="statusCode">The status code.</param>
        /// <param name="errorCode">The error code.</param>
        /// <param name="mapping">The mapping.</param>
        public void UpdateMapping(
            HttpStatusCode statusCode,
            string errorCode,
            Func <ResponseContent, HttpResponseExceptionContext, Exception> mapping)
        {
            var registration = new ErrorRegistration(statusCode, errorCode);

            if (!this.mappings.ContainsKey(registration))
            {
                throw new InvalidOperationException(
                          $"HTTP response to exception mapping is not registered for response status code {statusCode} and error code {errorCode}");
            }

            this.mappings[registration] = mapping;
        }
        /// <summary>
        /// Adds a mapping.
        /// </summary>
        /// <param name="statusCode">The status code.</param>
        /// <param name="errorCode">The error code.</param>
        /// <param name="mapping">The mapping.</param>
        public void AddMapping(
            HttpStatusCode statusCode,
            string errorCode,
            Func <ResponseContent, HttpResponseExceptionContext, Exception> mapping)
        {
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            var errorRegistration = new ErrorRegistration(statusCode, errorCode);

            if (this.mappings.ContainsKey(errorRegistration))
            {
                throw new InvalidOperationException(
                          $"HTTP response to exception mapping is already registered for response status code {errorRegistration.StatusCode} and error code {errorRegistration.ErrorCode}");
            }

            this.mappings.Add(errorRegistration, mapping);
        }
예제 #4
0
        /// <inheritdoc />
        public async Task <Exception> GetException(HttpResponseMessage response)
        {
            var statusCode      = response.StatusCode;
            var responseContent = await response.Content.ReadAsStringAsync();

            string errorCode;

            try
            {
                var jobject = JObject.Parse(responseContent);
                errorCode = jobject?.Property("code")?.Value?.Value <string>();
            }
            catch (Exception)
            {
                errorCode = null;
            }

            if (!string.IsNullOrWhiteSpace(errorCode))
            {
                // Search for both response code and error code match first
                var exactRegistration = new ErrorRegistration(statusCode, errorCode);
                if (this.mappers.Value.ContainsKey(exactRegistration))
                {
                    var mapper = this.mappers.Value[exactRegistration];
                    if (mapper == null)
                    {
                        var requestBody = await this.GetContent(response.RequestMessage?.Content);

                        return(await this.GetDefaultException(
                                   new RequestContent(response.RequestMessage, requestBody),
                                   new ResponseContent(response, responseContent),
                                   new HttpResponseExceptionContext(this.formatter)));
                    }

                    return(mapper.Invoke(
                               new ResponseContent(response, responseContent),
                               new HttpResponseExceptionContext(this.formatter)));
                }
            }

            // If no status code, error code match, then look for status code, null error code.
            var statusCodeMatchRegistration = new ErrorRegistration(statusCode, null);

            if (this.mappers.Value.ContainsKey(statusCodeMatchRegistration))
            {
                var mapper = this.mappers.Value[statusCodeMatchRegistration];
                if (mapper == null)
                {
                    var requestBody = await this.GetContent(response.RequestMessage?.Content);

                    return(await this.GetDefaultException(
                               new RequestContent(response.RequestMessage, requestBody),
                               new ResponseContent(response, responseContent),
                               new HttpResponseExceptionContext(this.formatter)));
                }

                return(mapper.Invoke(
                           new ResponseContent(response, responseContent),
                           new HttpResponseExceptionContext(this.formatter)));
            }

            var body = await this.GetContent(response.RequestMessage?.Content);

            return(await this.GetDefaultException(
                       new RequestContent(response.RequestMessage, body),
                       new ResponseContent(response, responseContent),
                       new HttpResponseExceptionContext(this.formatter)));
        }