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; }
/// <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); }
/// <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."); }
/// <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; }
/// <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); } }