Esempio n. 1
0
        /// <summary>
        /// Unpacks any exceptions in the given <see cref="HttpError"/> and adds
        /// them into a collection of name-value pairs that can be composed into a single string.
        /// </summary>
        /// <remarks>
        /// This helper also iterates over all inner exceptions and unpacks them too.
        /// </remarks>
        /// <param name="httpError">The <see cref="HttpError"/> to unpack.</param>
        /// <param name="messages">A collection of messages to which the new information should be added.</param>
        private static void AddExceptions(HttpError httpError, List <string> messages)
        {
            Contract.Assert(httpError != null);
            Contract.Assert(messages != null);

            object exceptionMessageObject = null;
            object exceptionTypeObject    = null;
            object stackTraceObject       = null;
            object innerExceptionObject   = null;

            for (int i = 0; httpError != null; i++)
            {
                // For uniqueness, key names append the depth of inner exception
                string indexText = i == 0 ? String.Empty : Error.Format("[{0}]", i);

                if (httpError.TryGetValue(HttpErrorKeys.ExceptionTypeKey, out exceptionTypeObject))
                {
                    messages.Add(
                        Error.Format(HttpErrorExceptionTypeFormat, indexText, exceptionTypeObject)
                        );
                }

                if (
                    httpError.TryGetValue(
                        HttpErrorKeys.ExceptionMessageKey,
                        out exceptionMessageObject
                        )
                    )
                {
                    messages.Add(
                        Error.Format(
                            HttpErrorExceptionMessageFormat,
                            indexText,
                            exceptionMessageObject
                            )
                        );
                }

                if (httpError.TryGetValue(HttpErrorKeys.StackTraceKey, out stackTraceObject))
                {
                    messages.Add(
                        Error.Format(HttpErrorStackTraceFormat, indexText, stackTraceObject)
                        );
                }

                if (
                    !httpError.TryGetValue(
                        HttpErrorKeys.InnerExceptionKey,
                        out innerExceptionObject
                        )
                    )
                {
                    break;
                }

                Contract.Assert(!Object.ReferenceEquals(httpError, innerExceptionObject));

                httpError = innerExceptionObject as HttpError;
            }
        }
        /// <summary>
        /// Unwraps an arbitrarily deep collection of inner exceptions inside an
        /// <see cref="HttpError"/> instance into a list of error messages.
        /// </summary>
        /// <param name="httpError">The input <see cref="HttpError"/>.</param>
        /// <param name="messages">The list of messages to which the exceptions should be added.</param>
        private static void AddExceptions(HttpError httpError, List <string> messages)
        {
            object exceptionMessageObject = null;
            object exceptionTypeObject    = null;
            object stackTraceObject       = null;
            object innerExceptionObject   = null;

            for (int i = 0; httpError != null; i++)
            {
                // For uniqueness, key names append the depth of inner exception
                string indexText = i == 0 ? String.Empty : String.Format("[{0}]", i);

                if (httpError.TryGetValue(ExceptionTypeKey, out exceptionTypeObject))
                {
                    messages.Add(String.Format(SRResources.HttpErrorExceptionTypeFormat, indexText, exceptionTypeObject));
                }

                if (httpError.TryGetValue(ExceptionMessageKey, out exceptionMessageObject))
                {
                    messages.Add(String.Format(SRResources.HttpErrorExceptionMessageFormat, indexText, exceptionMessageObject));
                }

                if (httpError.TryGetValue(StackTraceKey, out stackTraceObject))
                {
                    messages.Add(String.Format(SRResources.HttpErrorStackTraceFormat, indexText, stackTraceObject));
                }

                if (!httpError.TryGetValue(InnerExceptionKey, out innerExceptionObject))
                {
                    break;
                }

                httpError = innerExceptionObject as HttpError;
            }
        }
    public static ModelStateDictionary GetModelState(this HttpError httpError)
    {
        // Ensure.Argument.NotNull(httpError, "httpError");

        object serialized;

        if (httpError.TryGetValue("ModelState", out serialized))
        {
            var modelState = new ModelStateDictionary();

            var errors = (HttpError)httpError["ModelState"];

            foreach (var error in errors)
            {
                foreach (var message in error.Value as string[])
                {
                    modelState.AddModelError(error.Key, message);
                }
            }

            return(modelState);
        }

        return(null);
    }
Esempio n. 4
0
        /// <summary>
        /// Map the HTTP error to a JsonApiError.
        /// </summary>
        /// <param name="httpError">The HTTP error to map.</param>
        /// <returns>The JSON API error that was mapped from the HTTP Error.</returns>
        static JsonApiError Map(HttpError httpError)
        {
            var error = new JsonApiError {
                Status = "500", Code = "500"
            };

            if (httpError.TryGetValue("Message", out object value))
            {
                error.Title = value.ToString();
            }

            if (httpError.TryGetValue("ExceptionMessage", out value))
            {
                error.Detail = value.ToString();
            }

            return(error);
        }
Esempio n. 5
0
        private void LogExceptionDetails(HttpError error)
        {
            if (Logger.IsDebugEnabled)
            {
                object detail;
                if (error.TryGetValue("ExceptionType", out detail))
                {
                    Logger.DebugFormat("Remote Exception Type: {0}", detail);
                }

                Logger.Debug(error.ExceptionMessage ?? error.Message);

                if (error.TryGetValue("StackTrace", out detail))
                {
                    Logger.DebugFormat("Remote Stack Trace: {0}", detail);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        ///		Deserializes the HTTP error.
        /// </summary>
        /// <param name="existingError">The existing error.</param>
        /// <returns></returns>
        public static HttpError DeserializeHttpError(HttpError existingError)
        {
            if (existingError == null)
            {
                return(null);
            }

            var error = new HttpError( );

            object value;

            if (existingError.TryGetValue(HttpErrorKeys.MessageKey, out value))
            {
                error.Message = GetStringValue(value);
            }

            if (existingError.TryGetValue(HttpErrorKeys.ExceptionMessageKey, out value))
            {
                error.ExceptionMessage = GetStringValue(value);
            }

            if (existingError.TryGetValue(HttpErrorKeys.ExceptionTypeKey, out value))
            {
                error.ExceptionType = GetStringValue(value);
            }

            if (existingError.TryGetValue(HttpErrorKeys.StackTraceKey, out value))
            {
                error.StackTrace = GetStringValue(value);
            }

            if (existingError.TryGetValue(AdditionalInfoKey, out value))
            {
                error [AdditionalInfoKey] = GetStringValue(value);
            }

            if (existingError.TryGetValue(PasswordExpiredKey, out value))
            {
                error [PasswordExpiredKey] = GetStringValue(value);
            }

            if (existingError.TryGetValue(ValidationErrorKey, out value))
            {
                error [ValidationErrorKey] = GetStringValue(value);
            }

            return(error);
        }
        /// <summary>
        /// Unpacks any exceptions in the given <see cref="HttpError"/> and adds
        /// them into a collection of name-value pairs that can be composed into a single string.
        /// </summary>
        /// <remarks>
        /// This helper also iterates over all inner exceptions and unpacks them too.
        /// </remarks>
        /// <param name="httpError">The <see cref="HttpError"/> to unpack.</param>
        /// <param name="messages">A collection of messages to which the new information should be added.</param>
        private static void AddExceptions(HttpError httpError, List<string> messages)
        {
            Contract.Assert(httpError != null);
            Contract.Assert(messages != null);

            object exceptionMessageObject = null;
            object exceptionTypeObject = null;
            object stackTraceObject = null;
            object innerExceptionObject = null;

            for (int i = 0; httpError != null; i++)
            {
                // For uniqueness, key names append the depth of inner exception
                string indexText = i == 0 ? String.Empty : Error.Format("[{0}]", i);

                if (httpError.TryGetValue(ExceptionTypeKey, out exceptionTypeObject))
                {
                    messages.Add(Error.Format(SRResources.HttpErrorExceptionTypeFormat, indexText, exceptionTypeObject));
                }

                if (httpError.TryGetValue(ExceptionMessageKey, out exceptionMessageObject))
                {
                    messages.Add(Error.Format(SRResources.HttpErrorExceptionMessageFormat, indexText, exceptionMessageObject));
                }

                if (httpError.TryGetValue(StackTraceKey, out stackTraceObject))
                {
                    messages.Add(Error.Format(SRResources.HttpErrorStackTraceFormat, indexText, stackTraceObject));
                }

                if (!httpError.TryGetValue(InnerExceptionKey, out innerExceptionObject))
                {
                    break;
                }

                Contract.Assert(!Object.ReferenceEquals(httpError, innerExceptionObject));

                httpError = innerExceptionObject as HttpError;
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Examines the given <see cref="TraceRecord"/> to determine whether it
        /// contains an <see cref="HttpResponseException"/> and if so, modifies
        /// the <see cref="TraceRecord"/> to capture more detailed information.
        /// </summary>
        /// <param name="traceRecord">The <see cref="TraceRecord"/> to examine and modify.</param>
        public static void TranslateHttpResponseException(TraceRecord traceRecord)
        {
            Contract.Assert(traceRecord != null);

            HttpResponseException httpResponseException = ExtractHttpResponseException(
                traceRecord.Exception
                );

            if (httpResponseException == null)
            {
                return;
            }

            HttpResponseMessage response = httpResponseException.Response;

            Contract.Assert(response != null);

            // If the status has been set already, do not overwrite it,
            // otherwise propagate the status into the record.
            if (traceRecord.Status == 0)
            {
                traceRecord.Status = response.StatusCode;
            }

            traceRecord.Level = GetMappedTraceLevel(httpResponseException) ?? traceRecord.Level;

            // HttpResponseExceptions often contain HttpError instances that carry
            // detailed information that may be filtered out by IncludeErrorDetailPolicy
            // before reaching the client. Capture it here for the trace.
            ObjectContent objectContent = response.Content as ObjectContent;

            if (objectContent == null)
            {
                return;
            }

            HttpError httpError = objectContent.Value as HttpError;

            if (httpError == null)
            {
                return;
            }

            object messageObject        = null;
            object messageDetailsObject = null;

            List <string> messages = new List <string>();

            if (httpError.TryGetValue(HttpErrorKeys.MessageKey, out messageObject))
            {
                messages.Add(Error.Format(HttpErrorUserMessageFormat, messageObject));
            }

            if (httpError.TryGetValue(HttpErrorKeys.MessageDetailKey, out messageDetailsObject))
            {
                messages.Add(Error.Format(HttpErrorMessageDetailFormat, messageDetailsObject));
            }

            // Extract the exception from this HttpError and then incrementally
            // walk down all inner exceptions.
            AddExceptions(httpError, messages);

            // ModelState errors are handled with a nested HttpError
            object modelStateErrorObject = null;

            if (httpError.TryGetValue(HttpErrorKeys.ModelStateKey, out modelStateErrorObject))
            {
                HttpError modelStateError = modelStateErrorObject as HttpError;
                if (modelStateError != null)
                {
                    messages.Add(FormatModelStateErrors(modelStateError));
                }
            }

            traceRecord.Message = String.Join(", ", messages);
        }
        /// <summary>
        /// If the given <see cref="TraceRecord"/> contains an <see cref="HttpResponseException"/>,
        /// this method unwraps the information inside into a more human-readable form for tracing.
        /// </summary>
        /// <param name="traceRecord">The <see cref="TraceRecord"/> to examine and optionally modify.</param>
        /// <remarks>
        /// The WebAPI stack uses <see cref="HttpResponseException"/> to emit an
        /// <see cref="HttpResponseMessage"/> due to an recoverable error condition,
        /// such as an invalid user request.
        /// </remarks>
        private static void TranslateHttpResponseException(TraceRecord traceRecord)
        {
            HttpResponseException httpResponseException = traceRecord.Exception as HttpResponseException;

            if (httpResponseException != null)
            {
                HttpResponseMessage response = httpResponseException.Response;

                // If the status has been set already, do not overwrite it,
                // otherwise propagate the status into the record.
                if (traceRecord.Status == 0)
                {
                    traceRecord.Status = response.StatusCode;
                }

                // Client level errors are downgraded to TraceLevel.Warn
                if ((int)response.StatusCode < (int)HttpStatusCode.InternalServerError)
                {
                    traceRecord.Level = TraceLevel.Warn;
                }

                // HttpResponseExceptions often contain HttpError instances that carry
                // detailed information that may be filtered out by IncludeErrorDetailPolicy
                // before reaching the client. Capture it here for the trace.
                ObjectContent objectContent = response.Content as ObjectContent;
                if (objectContent != null)
                {
                    HttpError httpError = objectContent.Value as HttpError;
                    if (httpError != null)
                    {
                        // Having a structured HttpError replaces the normal
                        // exception in the record because it has more user-directed
                        // information.
                        traceRecord.Exception = null;

                        object messageObject        = null;
                        object messageDetailsObject = null;

                        List <string> messages = new List <string>();

                        if (httpError.TryGetValue(MessageKey, out messageObject))
                        {
                            messages.Add(String.Format(SRResources.HttpErrorUserMessageFormat, messageObject));
                        }

                        if (httpError.TryGetValue(MessageDetailKey, out messageDetailsObject))
                        {
                            messages.Add(String.Format(SRResources.HttpErrorMessageDetailFormat, messageDetailsObject));
                        }

                        // Extract the exception from this HttpError and then incrementally
                        // walk down all inner exceptions.
                        AddExceptions(httpError, messages);

                        // ModelState errors are handled with a nested HttpError
                        object modelStateErrorObject = null;
                        if (httpError.TryGetValue(ModelStateKey, out modelStateErrorObject))
                        {
                            HttpError modelStateError = modelStateErrorObject as HttpError;
                            if (modelStateError != null)
                            {
                                messages.Add(FormatModelStateErrors(modelStateError));
                            }
                        }

                        traceRecord.Message = String.Join(", ", messages);
                    }
                }
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Examines the given <see cref="TraceRecord"/> to determine whether it
        /// contains an <see cref="HttpResponseException"/> and if so, modifies
        /// the <see cref="TraceRecord"/> to capture more detailed information.
        /// </summary>
        /// <param name="traceRecord">The <see cref="TraceRecord"/> to examine and modify.</param>
        public virtual void TranslateHttpResponseException(TraceRecord traceRecord)
        {
            if (traceRecord == null)
            {
                throw Error.ArgumentNull("traceRecord");
            }

            var httpResponseException = ExtractHttpResponseException(traceRecord);

            if (httpResponseException == null)
            {
                return;
            }

            HttpResponseMessage response = httpResponseException.Response;

            Contract.Assert(response != null);

            // If the status has been set already, do not overwrite it,
            // otherwise propagate the status into the record.
            if (traceRecord.Status == 0)
            {
                traceRecord.Status = response.StatusCode;
            }

            // Client level errors are downgraded to TraceLevel.Warn
            if ((int)response.StatusCode < (int)HttpStatusCode.InternalServerError)
            {
                traceRecord.Level = TraceLevel.Warn;
            }

            // Non errors are downgraded to TraceLevel.Info
            if ((int)response.StatusCode < (int)HttpStatusCode.BadRequest)
            {
                traceRecord.Level = TraceLevel.Info;
            }

            // HttpResponseExceptions often contain HttpError instances that carry
            // detailed information that may be filtered out by IncludeErrorDetailPolicy
            // before reaching the client. Capture it here for the trace.
            ObjectContent objectContent = response.Content as ObjectContent;

            if (objectContent == null)
            {
                return;
            }

            HttpError httpError = objectContent.Value as HttpError;

            if (httpError == null)
            {
                return;
            }

            object messageObject        = null;
            object messageDetailsObject = null;

            List <string> messages = new List <string>();

            if (httpError.TryGetValue(MessageKey, out messageObject))
            {
                messages.Add(Error.Format(SRResources.HttpErrorUserMessageFormat, messageObject));
            }

            if (httpError.TryGetValue(MessageDetailKey, out messageDetailsObject))
            {
                messages.Add(Error.Format(SRResources.HttpErrorMessageDetailFormat, messageDetailsObject));
            }

            // Extract the exception from this HttpError and then incrementally
            // walk down all inner exceptions.
            AddExceptions(httpError, messages);

            // ModelState errors are handled with a nested HttpError
            object modelStateErrorObject = null;

            if (httpError.TryGetValue(ModelStateKey, out modelStateErrorObject))
            {
                HttpError modelStateError = modelStateErrorObject as HttpError;
                if (modelStateError != null)
                {
                    messages.Add(FormatModelStateErrors(modelStateError));
                }
            }

            traceRecord.Message = String.Join(", ", messages);
        }