private static ODataInnerError ToODataInnerError(HttpError httpError)
 {
     string innerErrorMessage = httpError.GetPropertyValue<string>(HttpErrorKeys.ExceptionMessageKey);
     if (innerErrorMessage == null)
     {
         string messageDetail = httpError.GetPropertyValue<string>(HttpErrorKeys.MessageDetailKey);
         if (messageDetail == null)
         {
             HttpError modelStateError = httpError.GetPropertyValue<HttpError>(HttpErrorKeys.ModelStateKey);
             return (modelStateError == null) ? null
                 : new ODataInnerError { Message = ConvertModelStateErrors(modelStateError) };
         }
         else
         {
             return new ODataInnerError() { Message = messageDetail };
         }
     }
     else
     {
         ODataInnerError innerError = new ODataInnerError();
         innerError.Message = innerErrorMessage;
         innerError.TypeName = httpError.GetPropertyValue<string>(HttpErrorKeys.ExceptionTypeKey);
         innerError.StackTrace = httpError.GetPropertyValue<string>(HttpErrorKeys.StackTraceKey);
         HttpError innerExceptionError = httpError.GetPropertyValue<HttpError>(HttpErrorKeys.InnerExceptionKey);
         if (innerExceptionError != null)
         {
             innerError.InnerError = ToODataInnerError(innerExceptionError);
         }
         return innerError;
     }
 }
        public void PropertyGettersAndSettersTest()
        {
            string errorCode = "500";
            string message = "Fehler! Bitte kontaktieren Sie den Administrator!";
            var target = "any target";
            var details = new List<ODataErrorDetail>
            {
                new ODataErrorDetail { ErrorCode = "401", Message = "any msg", Target = "another target" }
            };
            ODataInnerError innerError = new ODataInnerError { Message = "No inner error" };

            ODataError error = new ODataError()
            {
                ErrorCode = errorCode,
                Message = message,
                Target = target,
                Details = details,
                InnerError = innerError
            };

            this.Assert.AreEqual(errorCode, error.ErrorCode, "Expected equal error code values.");
            this.Assert.AreEqual(message, error.Message, "Expected equal message values.");
            this.Assert.AreEqual(target, error.Target, "Expected equal target values.");
            this.Assert.AreSame(details, error.Details, "Expected equal error detail values.");
            this.Assert.AreSame(innerError, error.InnerError, "Expected equal inner error values.");
        }
 public void DefaultValuesTest()
 {
     ODataInnerError innerError = new ODataInnerError();
     this.Assert.IsNull(innerError.Message, "Expected null default value for property 'Message'.");
     this.Assert.IsNull(innerError.TypeName, "Expected null default value for property 'TypeName'.");
     this.Assert.IsNull(innerError.StackTrace, "Expected null default value for property 'StackTrace'.");
     this.Assert.IsNull(innerError.InnerError, "Expected null default value for property 'InnerError'.");
 }
        /// <summary>
        /// Compares two <see cref="ODataInnerError"/> instances and returns true if they are equal. Otherwise returns false.
        /// </summary>
        /// <param name="first">The first <see cref="ODataInnerError"/> to use in the comparison.</param>
        /// <param name="second">The second <see cref="ODataInnerError"/> to use in the comparison.</param>
        /// <returns>true if the <paramref name="first"/> and <paramref name="second"/> inner error instances are equal; otherwise false.</returns>
        internal static bool AreEqual(ODataInnerError first, ODataInnerError second)
        {
            if (first == null && second == null) return true;
            if (first == null || second == null) return false;

            if (string.CompareOrdinal(first.Message, second.Message) != 0) return false;
            if (string.CompareOrdinal(first.TypeName, second.TypeName) != 0) return false;
            if (string.CompareOrdinal(first.StackTrace, second.StackTrace) != 0) return false;
            if (!AreEqual(first.InnerError, second.InnerError)) return false;

            return true;
        }
Exemple #5
0
        /// <summary>
        /// Write an error message.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="error">The error instance to write.</param>
        /// <param name="includeDebugInformation">A flag indicating whether error details should be written (in debug mode only) or not.</param>
        /// <param name="maxInnerErrorDepth">The maximumum number of nested inner errors to allow.</param>
        internal static void WriteXmlError(XmlWriter writer, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(error != null, "error != null");

            string code, message;

            ErrorUtils.GetErrorDetails(error, out code, out message);

            ODataInnerError innerError = includeDebugInformation ? error.InnerError : null;

            WriteXmlError(writer, code, message, innerError, maxInnerErrorDepth);
        }
Exemple #6
0
        /// <summary>
        /// Writes the inner exception information in debug mode.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="innerError">The inner error to write.</param>
        /// <param name="innerErrorElementName">The local name of the element representing the inner error.</param>
        /// <param name="recursionDepth">The number of times this method has been called recursively.</param>
        /// <param name="maxInnerErrorDepth">The maximumum number of nested inner errors to allow.</param>
        private static void WriteXmlInnerError(XmlWriter writer, ODataInnerError innerError, string innerErrorElementName, int recursionDepth, int maxInnerErrorDepth)
        {
            Debug.Assert(writer != null, "writer != null");

            recursionDepth++;
            if (recursionDepth > maxInnerErrorDepth)
            {
#if ODATALIB
                throw new ODataException(Strings.ValidationUtils_RecursionDepthLimitReached(maxInnerErrorDepth));
#else
                throw new ODataException(Microsoft.OData.Service.Strings.BadRequest_DeepRecursion(maxInnerErrorDepth));
#endif
            }

            // <m:innererror> or <m:internalexception>
            writer.WriteStartElement(AtomConstants.ODataMetadataNamespacePrefix, innerErrorElementName, AtomConstants.ODataMetadataNamespace);

            //// NOTE: we add empty elements if no information is provided for the message, error type and stack trace
            ////       to stay compatible with Astoria.

            // <m:message>...</m:message>
            string errorMessage = innerError.Message ?? String.Empty;
            writer.WriteStartElement(AtomConstants.ODataInnerErrorMessageElementName, AtomConstants.ODataMetadataNamespace);
            writer.WriteString(errorMessage);
            writer.WriteEndElement();

            // <m:type>...</m:type>
            string errorType = innerError.TypeName ?? string.Empty;
            writer.WriteStartElement(AtomConstants.ODataInnerErrorTypeElementName, AtomConstants.ODataMetadataNamespace);
            writer.WriteString(errorType);
            writer.WriteEndElement();

            // <m:stacktrace>...</m:stacktrace>
            string errorStackTrace = innerError.StackTrace ?? String.Empty;
            writer.WriteStartElement(AtomConstants.ODataInnerErrorStackTraceElementName, AtomConstants.ODataMetadataNamespace);
            writer.WriteString(errorStackTrace);
            writer.WriteEndElement();

            if (innerError.InnerError != null)
            {
                WriteXmlInnerError(writer, innerError.InnerError, AtomConstants.ODataInnerErrorInnerErrorElementName, recursionDepth, maxInnerErrorDepth);
            }

            // </m:innererror> or </m:internalexception>
            writer.WriteEndElement();
        }
        public void PropertyGettersAndSettersTest()
        {
            string errorCode = "500";
            string message = "Fehler! Bitte kontaktieren Sie den Administrator!";
            ODataInnerError innerError = new ODataInnerError { Message = "No inner error" };

            ODataError error = new ODataError()
            {
                ErrorCode = errorCode,
                Message = message,
                InnerError = innerError
            };

            this.Assert.AreEqual(errorCode, error.ErrorCode, "Expected equal error code values.");
            this.Assert.AreEqual(message, error.Message, "Expected equal message values.");
            this.Assert.AreSame(innerError, error.InnerError, "Expected equal inner error values.");
        }
        public void PropertySettersNullTest()
        {
            ODataInnerError innerError = new ODataInnerError()
                {
                    Message = "Fehler! Bitte kontaktieren Sie den Administrator!",
                    TypeName = "System.InvalidOperationException",
                    StackTrace = "Stack trace.",
                    InnerError = new ODataInnerError()
                };

            innerError.Message = null;
            innerError.TypeName = null;
            innerError.StackTrace = null;
            innerError.InnerError = null;

            this.Assert.IsNull(innerError.Message, "Expected null value for property 'Message'.");
            this.Assert.IsNull(innerError.TypeName, "Expected null value for property 'TypeName'.");
            this.Assert.IsNull(innerError.StackTrace, "Expected null value for property 'StackTrace'.");
            this.Assert.IsNull(innerError.InnerError, "Expected null value for property 'InnerError'.");
        }
        public void PropertyGettersAndSettersTest()
        {
            string message = "Fehler! Bitte kontaktieren Sie den Administrator!";
            string typeName = "System.InvalidOperationException";
            string stackTrace = "Stack trace.";
            ODataInnerError innerInnerError = new ODataInnerError();

            ODataInnerError innerError = new ODataInnerError()
            {
                Message = message,
                TypeName = typeName,
                StackTrace = stackTrace,
                InnerError = innerInnerError
            };

            this.Assert.AreEqual(message, innerError.Message, "Expected equal message values.");
            this.Assert.AreEqual(typeName, innerError.TypeName, "Expected equal type name values.");
            this.Assert.AreEqual(stackTrace, innerError.StackTrace, "Expected equal stack trace values.");
            this.Assert.AreSame(innerInnerError, innerError.InnerError, "Expected reference equal inner error values.");
        }
Exemple #10
0
        /// <summary>
        /// Write an error message.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="code">The code of the error.</param>
        /// <param name="message">The message of the error.</param>
        /// <param name="innerError">Inner error details that will be included in debug mode (if present).</param>
        /// <param name="maxInnerErrorDepth">The maximumum number of nested inner errors to allow.</param>
        private static void WriteXmlError(XmlWriter writer, string code, string message, ODataInnerError innerError, int maxInnerErrorDepth)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(code != null, "code != null");
            Debug.Assert(message != null, "message != null");

            // <m:error>
            writer.WriteStartElement(AtomConstants.ODataMetadataNamespacePrefix, AtomConstants.ODataErrorElementName, AtomConstants.ODataMetadataNamespace);

            // <m:code>code</m:code>
            writer.WriteElementString(AtomConstants.ODataMetadataNamespacePrefix, AtomConstants.ODataErrorCodeElementName, AtomConstants.ODataMetadataNamespace, code);

            // <m:message>error message</m:message>
            writer.WriteElementString(AtomConstants.ODataMetadataNamespacePrefix, AtomConstants.ODataErrorMessageElementName, AtomConstants.ODataMetadataNamespace, message);

            if (innerError != null)
            {
                WriteXmlInnerError(writer, innerError, AtomConstants.ODataInnerErrorElementName, /* recursionDepth */ 0, maxInnerErrorDepth);
            }

            // </m:error>
            writer.WriteEndElement();
        }
Exemple #11
0
        /// <summary>
        /// Write an error message.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="code">The code of the error.</param>
        /// <param name="message">The message of the error.</param>
        /// <param name="innerError">Inner error details that will be included in debug mode (if present).</param>
        /// <param name="maxInnerErrorDepth">The maximumum number of nested inner errors to allow.</param>
        private static void WriteXmlError(XmlWriter writer, string code, string message, ODataInnerError innerError, int maxInnerErrorDepth)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(code != null, "code != null");
            Debug.Assert(message != null, "message != null");

            // <m:error>
            writer.WriteStartElement(AtomConstants.ODataMetadataNamespacePrefix, AtomConstants.ODataErrorElementName, AtomConstants.ODataMetadataNamespace);

            // <m:code>code</m:code>
            writer.WriteElementString(AtomConstants.ODataMetadataNamespacePrefix, AtomConstants.ODataErrorCodeElementName, AtomConstants.ODataMetadataNamespace, code);

            // <m:message>error message</m:message>
            writer.WriteElementString(AtomConstants.ODataMetadataNamespacePrefix, AtomConstants.ODataErrorMessageElementName, AtomConstants.ODataMetadataNamespace, message);

            if (innerError != null)
            {
                WriteXmlInnerError(writer, innerError, AtomConstants.ODataInnerErrorElementName, /* recursionDepth */ 0, maxInnerErrorDepth);
            }

            // </m:error>
            writer.WriteEndElement();
        }
        public override void Visit(ODataInternalExceptionPayload payloadElement)
        {
            ODataInnerError innerError = new ODataInnerError()
            {
                Message = payloadElement.Message,
                TypeName = payloadElement.TypeName,
                StackTrace = payloadElement.StackTrace,
            };

            this.items.Push(innerError);
            base.Visit(payloadElement);
            
            //This should now have its innerError set if one exists
            innerError = this.items.Pop() as ODataInnerError;

            var higherLevel = this.items.Peek();
            var error = higherLevel as ODataError;
            if (error != null)
            {
                error.InnerError = innerError;
            }
            else
            {
                var higherLevelInnerError = higherLevel as ODataInnerError;
                ExceptionUtilities.CheckObjectNotNull(higherLevelInnerError, "Expected ODataError or ODataInnerError");
                higherLevelInnerError.InnerError = innerError;
            }
        }
        /// <summary>
        /// Converts an <see cref="ODataInternalExceptionPayload"/> into the corresponding <see cref="ODataInnerError"/>.
        /// </summary>
        /// <param name="innerErrorPayload">The inner error payload to convert.</param>
        /// <returns>A new <see cref="ODataInnerError"/> representing the <paramref name="innerErrorPayload"/>.</returns>
        private static ODataInnerError ConvertInnerErrorPayload(ODataInternalExceptionPayload innerErrorPayload)
        {
            ODataInnerError innerError = new ODataInnerError();

            innerError.Message = innerErrorPayload.Message;
            innerError.TypeName = innerErrorPayload.TypeName;
            innerError.StackTrace = innerErrorPayload.StackTrace;

            ODataInternalExceptionPayload nestedInnerErrorPayload = innerErrorPayload.InternalException;
            if (nestedInnerErrorPayload != null)
            {
                innerError.InnerError = ConvertInnerErrorPayload(nestedInnerErrorPayload);
            }

            return innerError;
        }
Exemple #14
0
        /// <summary>
        /// Writes the inner exception information in debug mode.
        /// </summary>
        /// <param name="writer">The Xml writer to write to.</param>
        /// <param name="innerError">The inner error to write.</param>
        /// <param name="innerErrorElementName">The local name of the element representing the inner error.</param>
        /// <param name="recursionDepth">The number of times this method has been called recursively.</param>
        /// <param name="maxInnerErrorDepth">The maximumum number of nested inner errors to allow.</param>
        private static void WriteXmlInnerError(XmlWriter writer, ODataInnerError innerError, string innerErrorElementName, int recursionDepth, int maxInnerErrorDepth)
        {
            Debug.Assert(writer != null, "writer != null");

            recursionDepth++;
            if (recursionDepth > maxInnerErrorDepth)
            {
#if ODATALIB
                throw new ODataException(Strings.ValidationUtils_RecursionDepthLimitReached(maxInnerErrorDepth));
#else
                throw new ODataException(Microsoft.OData.Service.Strings.BadRequest_DeepRecursion(maxInnerErrorDepth));
#endif
            }

            // <m:innererror> or <m:internalexception>
            writer.WriteStartElement(AtomConstants.ODataMetadataNamespacePrefix, innerErrorElementName, AtomConstants.ODataMetadataNamespace);

            //// NOTE: we add empty elements if no information is provided for the message, error type and stack trace
            ////       to stay compatible with Astoria.

            // <m:message>...</m:message>
            string errorMessage = innerError.Message ?? String.Empty;
            writer.WriteStartElement(AtomConstants.ODataInnerErrorMessageElementName, AtomConstants.ODataMetadataNamespace);
            writer.WriteString(errorMessage);
            writer.WriteEndElement();

            // <m:type>...</m:type>
            string errorType = innerError.TypeName ?? string.Empty;
            writer.WriteStartElement(AtomConstants.ODataInnerErrorTypeElementName, AtomConstants.ODataMetadataNamespace);
            writer.WriteString(errorType);
            writer.WriteEndElement();

            // <m:stacktrace>...</m:stacktrace>
            string errorStackTrace = innerError.StackTrace ?? String.Empty;
            writer.WriteStartElement(AtomConstants.ODataInnerErrorStackTraceElementName, AtomConstants.ODataMetadataNamespace);
            writer.WriteString(errorStackTrace);
            writer.WriteEndElement();

            if (innerError.InnerError != null)
            {
                WriteXmlInnerError(writer, innerError.InnerError, AtomConstants.ODataInnerErrorInnerErrorElementName, recursionDepth, maxInnerErrorDepth);
            }

            // </m:innererror> or </m:internalexception>
            writer.WriteEndElement();
        }
 /// <summary>
 /// Visits an inner error.
 /// </summary>
 /// <param name="innerError">The inner error to visit.</param>
 protected virtual void VisitInnerError(ODataInnerError innerError)
 {
     ODataInnerError nestedInnerError = innerError.InnerError;
     if (nestedInnerError != null)
     {
         this.Visit(nestedInnerError);
     }
 }