/// <summary> /// Asynchronously writes an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error.</param> /// <param name="writeInstanceAnnotationsDelegate">Delegate to write the instance annotations.</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 maximum number of nested inner errors to allow.</param> /// <returns>A task that represents the asynchronous write operation.</returns> internal static Task WriteErrorAsync( IJsonWriterAsync jsonWriter, Func <ICollection <ODataInstanceAnnotation>, Task> writeInstanceAnnotationsDelegate, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(error != null, "error != null"); ExceptionUtils.CheckArgumentNotNull(writeInstanceAnnotationsDelegate, "writeInstanceAnnotationsDelegate"); string code, message; ErrorUtils.GetErrorDetails(error, out code, out message); ODataInnerError innerError = includeDebugInformation ? error.InnerError : null; return(WriteErrorAsync( jsonWriter, code, message, error.Target, error.Details, innerError, error.GetInstanceAnnotations(), writeInstanceAnnotationsDelegate, maxInnerErrorDepth)); }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error.</param> /// <param name="writeInstanceAnnotationsDelegate">Action to write the instance annotations.</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 maximum number of nested inner errors to allow.</param> /// <param name="writingJsonLight">true if we're writing JSON lite, false if we're writing verbose JSON.</param> internal static void WriteError( IJsonWriter jsonWriter, Action <ICollection <ODataInstanceAnnotation> > writeInstanceAnnotationsDelegate, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth, bool writingJsonLight) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(error != null, "error != null"); string code, message; ErrorUtils.GetErrorDetails(error, out code, out message); ODataInnerError innerError = includeDebugInformation ? error.InnerError : null; WriteError( jsonWriter, code, message, error.Target, error.Details, innerError, error.GetInstanceAnnotations(), writeInstanceAnnotationsDelegate, maxInnerErrorDepth, writingJsonLight); }
/// <summary> /// Write an inner error property and message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error to.</param> /// <param name="innerError">Inner error details.</param> /// <param name="innerErrorPropertyName">The property name for the inner error property.</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 WriteInnerError(JsonWriter jsonWriter, ODataInnerError innerError, string innerErrorPropertyName, int recursionDepth, int maxInnerErrorDepth) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(innerErrorPropertyName != null, "innerErrorPropertyName != null"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, maxInnerErrorDepth); // "innererror": { jsonWriter.WriteName(innerErrorPropertyName); jsonWriter.StartObjectScope(); //// NOTE: we add empty elements if no information is provided for the message, error type and stack trace //// to stay compatible with Astoria. // "message": "<message>" jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorMessageName); jsonWriter.WriteValue(innerError.Message ?? string.Empty); // "type": "<typename"> jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorTypeNameName); jsonWriter.WriteValue(innerError.TypeName ?? string.Empty); // "stacktrace": "<stacktrace>" jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorStackTraceName); jsonWriter.WriteValue(innerError.StackTrace ?? string.Empty); if (innerError.InnerError != null) { // "internalexception": { <nested inner error> } ODataJsonWriterUtils.WriteInnerError(jsonWriter, innerError.InnerError, JsonConstants.ODataErrorInnerErrorInnerErrorName, recursionDepth, maxInnerErrorDepth); } // } jsonWriter.EndObjectScope(); }
/// <summary> /// Reads an inner error payload. /// </summary> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <returns>An <see cref="ODataInnerError"/> representing the read inner error.</returns> /// <remarks> /// Pre-Condition: any - will throw if not StartObject /// Post-Condition: JsonNodeType.Property - The next property in the error value /// JsonNodeType.EndObject - The end of the error value /// </remarks> private ODataInnerError ReadInnerError(int recursionDepth) { Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "JsonReader.DisableInStreamErrorDetection"); this.JsonReader.AssertNotBuffering(); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.MessageReaderSettings.MessageQuotas.MaxNestingDepth); this.JsonReader.ReadStartObject(); ODataInnerError innerError = new ODataInnerError(); ODataJsonReaderUtils.ErrorPropertyBitMask propertiesFoundBitField = ODataJsonReaderUtils.ErrorPropertyBitMask.None; while (this.JsonReader.NodeType == JsonNodeType.Property) { string propertyName = this.JsonReader.ReadPropertyName(); switch (propertyName) { case JsonConstants.ODataErrorInnerErrorMessageName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.MessageValue, JsonConstants.ODataErrorInnerErrorMessageName); innerError.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorMessageName); break; case JsonConstants.ODataErrorInnerErrorTypeNameName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.TypeName, JsonConstants.ODataErrorInnerErrorTypeNameName); innerError.TypeName = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorTypeNameName); break; case JsonConstants.ODataErrorInnerErrorStackTraceName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.StackTrace, JsonConstants.ODataErrorInnerErrorStackTraceName); innerError.StackTrace = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorStackTraceName); break; case JsonConstants.ODataErrorInnerErrorInnerErrorName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.InnerError, JsonConstants.ODataErrorInnerErrorInnerErrorName); innerError.InnerError = this.ReadInnerError(recursionDepth); break; default: // skip any unsupported properties in the inner error this.JsonReader.SkipValue(); break; } } this.JsonReader.ReadEndObject(); this.JsonReader.AssertNotBuffering(); return(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> public 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); }
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> /// Reads a property value which occurs in the "innererror" object scope. /// </summary> /// <param name="recursionDepth">The number of parent inner errors for this inner error.</param> /// <param name="innerError">The <see cref="ODataError"/> object to update with the data from this property value.</param> /// <param name="propertyName">The name of the property whose value is to be read.</param> /// <remarks> /// Pre-Condition: any - The value of the property being read. /// Post-Condition: JsonNodeType.Property - The property after the one being read. /// JsonNodeType.EndObject - The end of the "innererror" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private void ReadPropertyValueInInnerError(int recursionDepth, ODataInnerError innerError, string propertyName) { switch (propertyName) { case JsonConstants.ODataErrorInnerErrorMessageName: innerError.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorMessageName); break; case JsonConstants.ODataErrorInnerErrorTypeNameName: innerError.TypeName = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorTypeNameName); break; case JsonConstants.ODataErrorInnerErrorStackTraceName: innerError.StackTrace = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorStackTraceName); break; case JsonConstants.ODataErrorInnerErrorInnerErrorName: innerError.InnerError = this.ReadInnerError(recursionDepth); break; default: // skip any unsupported properties in the inner error this.JsonReader.SkipValue(); break; } }
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."); }
/// <summary> /// Reads a property value which occurs in the "innererror" object scope. /// </summary> /// <param name="recursionDepth">The number of parent inner errors for this inner error.</param> /// <param name="innerError">The <see cref="ODataError"/> object to update with the data from this property value.</param> /// <param name="propertyName">The name of the property whose value is to be read.</param> /// <remarks> /// Pre-Condition: any - The value of the property being read. /// Post-Condition: JsonNodeType.Property - The property after the one being read. /// JsonNodeType.EndObject - The end of the "innererror" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private void ReadPropertyValueInInnerError(int recursionDepth, ODataInnerError innerError, string propertyName) { switch (propertyName) { case JsonConstants.ODataErrorInnerErrorMessageName: innerError.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorMessageName); break; case JsonConstants.ODataErrorInnerErrorTypeNameName: innerError.TypeName = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorTypeNameName); break; case JsonConstants.ODataErrorInnerErrorStackTraceName: innerError.StackTrace = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorStackTraceName); break; case JsonConstants.ODataErrorInnerErrorInnerErrorName: innerError.InnerError = this.ReadInnerError(recursionDepth); break; default: if (!innerError.Properties.ContainsKey(propertyName)) { innerError.Properties.Add(propertyName, this.JsonReader.ReadODataValue()); } else { innerError.Properties[propertyName] = this.JsonReader.ReadODataValue(); } break; } }
public async Task WriteErrorAsync_InnerErrorWithCollectionAndNulls() { ODataInnerError innerError = new ODataInnerError(); innerError.Properties.Add("ResourceValue", new ODataResourceValue { Properties = new ODataProperty[] { new ODataProperty { Name = "PropertyName", Value = "PropertyValue" }, new ODataProperty { Name = "NullProperty", Value = new ODataNullValue() } } }); innerError.Properties.Add("NullProperty", new ODataNullValue()); innerError.Properties.Add("CollectionValue", new ODataCollectionValue { Items = new List <object> { new ODataNullValue(), new ODataPrimitiveValue("CollectionValue"), new ODataPrimitiveValue(1) } }); var error = new ODataError { Target = "any target", Details = new[] { new ODataErrorDetail { ErrorCode = "500", Target = "any target", Message = "any msg" } }, InnerError = innerError }; await ODataJsonWriterUtils.WriteErrorAsync( this.jsonWriter, this.writeInstanceAnnotationsDelegate, error, includeDebugInformation : true, maxInnerErrorDepth : 5); var result = stringWriter.GetStringBuilder().ToString(); Assert.Equal("{\"error\":{" + "\"code\":\"\"," + "\"message\":\"\"," + "\"target\":\"any target\"," + "\"details\":[{\"code\":\"500\",\"target\":\"any target\",\"message\":\"any msg\"}]," + "\"innererror\":{" + "\"message\":\"\"," + "\"type\":\"\"," + "\"stacktrace\":\"\"," + "\"ResourceValue\":{\"PropertyName\":\"PropertyValue\",\"NullProperty\":null}," + "\"NullProperty\":null," + "\"CollectionValue\":[null,\"CollectionValue\",1]" + "}" + "}}", result); }
/// <summary> /// Visits an error. /// </summary> /// <param name="error">The error to visit.</param> protected virtual void VisitError(ODataError error) { ODataInnerError innerError = error.InnerError; if (innerError != null) { this.Visit(innerError); } }
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> /// 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); } }
internal static void WriteError(JsonWriter jsonWriter, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth) { string str; string str2; string str3; ErrorUtils.GetErrorDetails(error, out str, out str2, out str3); ODataInnerError innerError = includeDebugInformation ? error.InnerError : null; WriteError(jsonWriter, str, str2, str3, innerError, maxInnerErrorDepth); }
/// <summary> /// Visits an inner error. /// </summary> /// <param name="innerError">The inner error to visit.</param> protected override ODataPayloadElement VisitInnerError(ODataInnerError innerError) { if (innerError == null) { return(null); } return(PayloadBuilder.InnerError() .Message(innerError.Message) .TypeName(innerError.TypeName) .StackTrace(innerError.StackTrace) .InnerError(innerError.InnerError == null ? null : (ODataInternalExceptionPayload)this.Visit(innerError.InnerError))); }
private ODataInnerError ReadInnerError(int recursionDepth) { ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, base.MessageReaderSettings.MessageQuotas.MaxNestingDepth); base.JsonReader.ReadStartObject(); ODataInnerError error = new ODataInnerError(); ODataJsonReaderUtils.ErrorPropertyBitMask none = ODataJsonReaderUtils.ErrorPropertyBitMask.None; while (base.JsonReader.NodeType == JsonNodeType.Property) { string str2 = base.JsonReader.ReadPropertyName(); if (str2 == null) { goto Label_010E; } if (!(str2 == "message")) { if (str2 == "type") { goto Label_00A2; } if (str2 == "stacktrace") { goto Label_00C8; } if (str2 == "internalexception") { goto Label_00F1; } goto Label_010E; } ODataJsonReaderUtils.VerifyErrorPropertyNotFound(ref none, ODataJsonReaderUtils.ErrorPropertyBitMask.MessageValue, "message"); error.Message = base.JsonReader.ReadStringValue("message"); continue; Label_00A2: ODataJsonReaderUtils.VerifyErrorPropertyNotFound(ref none, ODataJsonReaderUtils.ErrorPropertyBitMask.TypeName, "type"); error.TypeName = base.JsonReader.ReadStringValue("type"); continue; Label_00C8: ODataJsonReaderUtils.VerifyErrorPropertyNotFound(ref none, ODataJsonReaderUtils.ErrorPropertyBitMask.StackTrace, "stacktrace"); error.StackTrace = base.JsonReader.ReadStringValue("stacktrace"); continue; Label_00F1: ODataJsonReaderUtils.VerifyErrorPropertyNotFound(ref none, ODataJsonReaderUtils.ErrorPropertyBitMask.InnerError, "internalexception"); error.InnerError = this.ReadInnerError(recursionDepth); continue; Label_010E: base.JsonReader.SkipValue(); } base.JsonReader.ReadEndObject(); return(error); }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error 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 WriteError(JsonWriter jsonWriter, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(error != null, "error != null"); string code, message, messageLanguage; ErrorUtils.GetErrorDetails(error, out code, out message, out messageLanguage); ODataInnerError innerError = includeDebugInformation ? error.InnerError : null; ODataJsonWriterUtils.WriteError(jsonWriter, code, message, messageLanguage, innerError, maxInnerErrorDepth); }
private static ODataInnerError ToODataInnerError(this Dictionary <string, object> errors) { string innerErrorMessage = errors.GetPropertyValue <string>(SerializableErrorKeys.ExceptionMessageKey); if (innerErrorMessage == null) { string messageDetail = errors.GetPropertyValue <string>(SerializableErrorKeys.MessageDetailKey); if (messageDetail == null) { SerializableError modelStateError = errors.GetPropertyValue <SerializableError>(SerializableErrorKeys.ModelStateKey); errors.Remove(SerializableErrorKeys.ModelStateKey); return((modelStateError == null) ? null : new ODataInnerError { Message = ConvertModelStateErrors(modelStateError) }); } errors.Remove(SerializableErrorKeys.MessageDetailKey); return(new ODataInnerError { Message = messageDetail }); } errors.Remove(SerializableErrorKeys.ExceptionMessageKey); ODataInnerError innerError = new ODataInnerError { Message = innerErrorMessage, TypeName = errors.GetPropertyValue <string>(SerializableErrorKeys.ExceptionTypeKey), StackTrace = errors.GetPropertyValue <string>(SerializableErrorKeys.StackTraceKey) }; errors.Remove(SerializableErrorKeys.ExceptionTypeKey); errors.Remove(SerializableErrorKeys.StackTraceKey); SerializableError innerExceptionError = errors.GetPropertyValue <SerializableError>(SerializableErrorKeys.InnerExceptionKey); errors.Remove(SerializableErrorKeys.InnerExceptionKey); if (innerExceptionError != null) { innerError.InnerError = ToODataInnerError(innerExceptionError); } return(innerError); }
/// <summary> /// Reads an inner error payload. /// </summary> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <returns>An <see cref="ODataInnerError"/> representing the read inner error.</returns> /// <remarks> /// Pre-Condition: JsonNodeType.StartObject - The start of the "innererror" object. /// any - will throw if not StartObject. /// Post-Condition: any - The node after the "innererror" object's EndNode. /// </remarks> private ODataInnerError ReadInnerError(int recursionDepth) { Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "JsonReader.DisableInStreamErrorDetection"); this.JsonReader.AssertNotBuffering(); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.MessageReaderSettings.MessageQuotas.MaxNestingDepth); ODataInnerError innerError = new ODataInnerError(); this.ReadJsonObjectInErrorPayload((propertyName, duplicatePropertyNamesChecker) => this.ReadPropertyValueInInnerError(recursionDepth, innerError, propertyName)); this.JsonReader.AssertNotBuffering(); return(innerError); }
/// <summary> /// Creates an exception message from the specified OData error. /// </summary> /// <param name="error">The OData error instance to create exception message for.</param> /// <returns>Exception message created from the <paramref name="error"/>.</returns> private static string CreateODataErrorExceptionMessage(ODataError error) { Debug.Assert(error != null, "error != null"); StringBuilder errorMessage = new StringBuilder(error.Message); ODataInnerError innerError = error.InnerError; while (innerError != null) { errorMessage.AppendLine(); errorMessage.Append(innerError.Message); innerError = innerError.InnerError; } return(errorMessage.ToString()); }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error.</param> /// <param name="writeInstanceAnnotationsDelegate">Action to write the instance annotations.</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> /// <param name="writingJsonLight">true if we're writing JSON lite, false if we're writing verbose JSON.</param> internal static void WriteError(IJsonWriter jsonWriter, Action <IEnumerable <ODataInstanceAnnotation> > writeInstanceAnnotationsDelegate, ODataError error, bool includeDebugInformation, int maxInnerErrorDepth, bool writingJsonLight) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(error != null, "error != null"); string code, message, messageLanguage; ErrorUtils.GetErrorDetails(error, out code, out message, out messageLanguage); ODataInnerError innerError = includeDebugInformation ? error.InnerError : null; var instanceAnnotations = error.GetInstanceAnnotationsForWriting(); WriteError(jsonWriter, code, message, messageLanguage, innerError, instanceAnnotations, writeInstanceAnnotationsDelegate, maxInnerErrorDepth, writingJsonLight); }
/// <summary> /// Asynchronously reads an inner error object. /// </summary> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <returns> /// A task that represents the asynchronous read operation. /// The value of the TResult parameter contains an <see cref="ODataInnerError"/> representing the read inner error. /// </returns> /// <remarks> /// Pre-Condition: JsonNodeType.StartObject - The start of the "innererror" object. /// any - will throw if not StartObject. /// Post-Condition: any - The node after the "innererror" object's EndNode. /// </remarks> private async Task <ODataInnerError> ReadInnerErrorAsync(int recursionDepth) { Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "JsonReader.DisableInStreamErrorDetection"); this.JsonReader.AssertNotBuffering(); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.MessageReaderSettings.MessageQuotas.MaxNestingDepth); ODataInnerError innerError = new ODataInnerError(); await this.ReadJsonObjectInErrorPayloadAsync( (propertyName, propertyAndAnnotationCollector) => this.ReadPropertyValueInInnerErrorAsync(recursionDepth, innerError, propertyName)).ConfigureAwait(false); this.JsonReader.AssertNotBuffering(); return(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); }
private static void WriteInnerError(JsonWriter jsonWriter, ODataInnerError innerError, string innerErrorPropertyName, int recursionDepth, int maxInnerErrorDepth) { ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, maxInnerErrorDepth); jsonWriter.WriteName(innerErrorPropertyName); jsonWriter.StartObjectScope(); jsonWriter.WriteName("message"); jsonWriter.WriteValue(innerError.Message ?? string.Empty); jsonWriter.WriteName("type"); jsonWriter.WriteValue(innerError.TypeName ?? string.Empty); jsonWriter.WriteName("stacktrace"); jsonWriter.WriteValue(innerError.StackTrace ?? string.Empty); if (innerError.InnerError != null) { WriteInnerError(jsonWriter, innerError.InnerError, "internalexception", recursionDepth, maxInnerErrorDepth); } jsonWriter.EndObjectScope(); }
/// <summary> /// Write an inner error property and message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error to.</param> /// <param name="innerError">Inner error details.</param> /// <param name="innerErrorPropertyName">The property name for the inner error property.</param> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param> private static void WriteInnerError( IJsonWriter jsonWriter, ODataInnerError innerError, string innerErrorPropertyName, int recursionDepth, int maxInnerErrorDepth) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(innerErrorPropertyName != null, "innerErrorPropertyName != null"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, maxInnerErrorDepth); // "innererror": jsonWriter.WriteName(innerErrorPropertyName); jsonWriter.StartObjectScope(); if (innerError.Properties != null) { foreach (KeyValuePair <string, ODataValue> pair in innerError.Properties) { jsonWriter.WriteName(pair.Key); if (pair.Value is ODataNullValue && (pair.Key == JsonConstants.ODataErrorInnerErrorMessageName || pair.Key == JsonConstants.ODataErrorInnerErrorStackTraceName || pair.Key == JsonConstants.ODataErrorInnerErrorTypeNameName)) { // Write empty string for null values in stacktrace, type and message properties of inner error. jsonWriter.WriteODataValue(new ODataPrimitiveValue(string.Empty)); } else { jsonWriter.WriteODataValue(pair.Value); } } } if (innerError.InnerError != null) { // "internalexception": { <nested inner error> } WriteInnerError(jsonWriter, innerError.InnerError, JsonConstants.ODataErrorInnerErrorInnerErrorName, recursionDepth, maxInnerErrorDepth); } // } jsonWriter.EndObjectScope(); }
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."); }
/// <summary> /// Asynchronously reads a property value which occurs in the "innererror" object scope. /// </summary> /// <param name="recursionDepth">The number of parent inner errors for this inner error.</param> /// <param name="innerError">The <see cref="ODataError"/> object to update with the data from this property value.</param> /// <param name="propertyName">The name of the property whose value is to be read.</param> /// <returns>A task that represents the asynchronous read operation.</returns> /// <remarks> /// Pre-Condition: any - The value of the property being read. /// Post-Condition: JsonNodeType.Property - The property after the one being read. /// JsonNodeType.EndObject - The end of the "innererror" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private async Task ReadPropertyValueInInnerErrorAsync(int recursionDepth, ODataInnerError innerError, string propertyName) { switch (propertyName) { case JsonConstants.ODataErrorInnerErrorMessageName: innerError.Message = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorInnerErrorMessageName) .ConfigureAwait(false); break; case JsonConstants.ODataErrorInnerErrorTypeNameName: innerError.TypeName = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorInnerErrorTypeNameName) .ConfigureAwait(false); break; case JsonConstants.ODataErrorInnerErrorStackTraceName: innerError.StackTrace = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorInnerErrorStackTraceName) .ConfigureAwait(false); break; case JsonConstants.ODataErrorInnerErrorInnerErrorName: innerError.InnerError = await this.ReadInnerErrorAsync(recursionDepth) .ConfigureAwait(false); break; default: if (!innerError.Properties.ContainsKey(propertyName)) { innerError.Properties.Add(propertyName, await this.JsonReader.ReadODataValueAsync().ConfigureAwait(false)); } else { innerError.Properties[propertyName] = await this.JsonReader.ReadODataValueAsync() .ConfigureAwait(false); } break; } }
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."); }
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'."); }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error to.</param> /// <param name="code">The code of the error.</param> /// <param name="message">The message of the error.</param> /// <param name="messageLanguage">The language of the message.</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 WriteError(JsonWriter jsonWriter, string code, string message, string messageLanguage, ODataInnerError innerError, int maxInnerErrorDepth) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(code != null, "code != null"); Debug.Assert(message != null, "message != null"); Debug.Assert(messageLanguage != null, "messageLanguage != null"); // { "error": { jsonWriter.StartObjectScope(); jsonWriter.WriteName(JsonConstants.ODataErrorName); jsonWriter.StartObjectScope(); // "code": "<code>" jsonWriter.WriteName(JsonConstants.ODataErrorCodeName); jsonWriter.WriteValue(code); // "message": { jsonWriter.WriteName(JsonConstants.ODataErrorMessageName); jsonWriter.StartObjectScope(); // "lang": "<messageLanguage>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageLanguageName); jsonWriter.WriteValue(messageLanguage); // "value": "<message>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageValueName); jsonWriter.WriteValue(message); // } jsonWriter.EndObjectScope(); if (innerError != null) { ODataJsonWriterUtils.WriteInnerError(jsonWriter, innerError, JsonConstants.ODataErrorInnerErrorName, /* recursionDepth */ 0, maxInnerErrorDepth); } // } } jsonWriter.EndObjectScope(); jsonWriter.EndObjectScope(); }
private static ODataInnerError ToODataInnerError(this HttpError httpError) { string innerErrorMessage = httpError.GetPropertyValue <string>(ExceptionMessageKey); if (innerErrorMessage == null) { return(null); } else { ODataInnerError innerError = new ODataInnerError(); innerError.Message = innerErrorMessage; innerError.TypeName = httpError.GetPropertyValue <string>(ExceptionTypeKey); innerError.StackTrace = httpError.GetPropertyValue <string>(StackTraceKey); HttpError innerExceptionError = httpError.GetPropertyValue <HttpError>(InnerExceptionKey); if (innerExceptionError != null) { innerError.InnerError = innerExceptionError.ToODataInnerError(); } return(innerError); } }
/// <summary> /// Reads an inner error payload. /// </summary> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <returns>An <see cref="ODataInnerError"/> representing the read inner error.</returns> /// <remarks> /// Pre-Condition: JsonNodeType.StartObject - The start of the "innererror" object. /// any - will throw if not StartObject. /// Post-Condition: any - The node after the "innererror" object's EndNode. /// </remarks> private ODataInnerError ReadInnerError(int recursionDepth) { Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "JsonReader.DisableInStreamErrorDetection"); this.JsonReader.AssertNotBuffering(); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.MessageReaderSettings.MessageQuotas.MaxNestingDepth); ODataInnerError innerError = new ODataInnerError(); this.ReadJsonObjectInErrorPayload((propertyName, duplicatePropertyNamesChecker) => this.ReadPropertyValueInInnerError(recursionDepth, innerError, propertyName)); this.JsonReader.AssertNotBuffering(); return innerError; }
/// <summary> /// Write an inner error property and message. /// </summary> /// <param name="jsonWriter">The JSON writer to write the error to.</param> /// <param name="innerError">Inner error details.</param> /// <param name="innerErrorPropertyName">The property name for the inner error property.</param> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param> private static void WriteInnerError(IJsonWriter jsonWriter, ODataInnerError innerError, string innerErrorPropertyName, int recursionDepth, int maxInnerErrorDepth) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(innerErrorPropertyName != null, "innerErrorPropertyName != null"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, maxInnerErrorDepth); // "innererror": { jsonWriter.WriteName(innerErrorPropertyName); jsonWriter.StartObjectScope(); //// NOTE: we add empty elements if no information is provided for the message, error type and stack trace //// to stay compatible with Astoria. // "message": "<message>" jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorMessageName); jsonWriter.WriteValue(innerError.Message ?? string.Empty); // "type": "<typename"> jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorTypeNameName); jsonWriter.WriteValue(innerError.TypeName ?? string.Empty); // "stacktrace": "<stacktrace>" jsonWriter.WriteName(JsonConstants.ODataErrorInnerErrorStackTraceName); jsonWriter.WriteValue(innerError.StackTrace ?? string.Empty); if (innerError.InnerError != null) { // "internalexception": { <nested inner error> } WriteInnerError(jsonWriter, innerError.InnerError, JsonConstants.ODataErrorInnerErrorInnerErrorName, recursionDepth, maxInnerErrorDepth); } // } jsonWriter.EndObjectScope(); }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">JSON writer.</param> /// <param name="code">The code of the error.</param> /// <param name="message">The message of the error.</param> /// <param name="target">The target of the error.</param> /// <param name="details">The details of the error.</param> /// <param name="innerError">Inner error details that will be included in debug mode (if present).</param> /// <param name="instanceAnnotations">Instance annotations for this error.</param> /// <param name="writeInstanceAnnotationsDelegate">Action to write the instance annotations.</param> /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param> /// <param name="writingJsonLight">true if we're writing JSON lite, false if we're writing verbose JSON.</param> private static void WriteError(IJsonWriter jsonWriter, string code, string message, string target, IEnumerable<ODataErrorDetail> details, ODataInnerError innerError, IEnumerable<ODataInstanceAnnotation> instanceAnnotations, Action<IEnumerable<ODataInstanceAnnotation>> writeInstanceAnnotationsDelegate, int maxInnerErrorDepth, bool writingJsonLight) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(code != null, "code != null"); Debug.Assert(message != null, "message != null"); Debug.Assert(instanceAnnotations != null, "instanceAnnotations != null"); // "error": { jsonWriter.StartObjectScope(); if (writingJsonLight) { jsonWriter.WriteName(JsonLightConstants.ODataErrorPropertyName); } else { jsonWriter.WriteName(JsonConstants.ODataErrorName); } jsonWriter.StartObjectScope(); // "code": "<code>" jsonWriter.WriteName(JsonConstants.ODataErrorCodeName); jsonWriter.WriteValue(code); // "message": "<message string>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageName); jsonWriter.WriteValue(message); // For example, "target": "query", if (target != null) { jsonWriter.WriteName(JsonConstants.ODataErrorTargetName); jsonWriter.WriteValue(target); } // Such as, "details": [ // { // "code": "301", // "target": "$search", // "message": "$search query option not supported" // }] if (details != null) { WriteErrorDetails(jsonWriter, details, JsonConstants.ODataErrorDetailsName); } if (innerError != null) { WriteInnerError(jsonWriter, innerError, JsonConstants.ODataErrorInnerErrorName, /* recursionDepth */ 0, maxInnerErrorDepth); } if (writingJsonLight) { Debug.Assert(writeInstanceAnnotationsDelegate != null, "writeInstanceAnnotations != null"); writeInstanceAnnotationsDelegate(instanceAnnotations); } // } } jsonWriter.EndObjectScope(); jsonWriter.EndObjectScope(); }
/// <summary> /// Write an error message. /// </summary> /// <param name="jsonWriter">JSON writer.</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="instanceAnnotations">Instance annotations for this error.</param> /// <param name="writeInstanceAnnotationsDelegate">Action to write the instance annotations.</param> /// <param name="maxInnerErrorDepth">The maximum number of nested inner errors to allow.</param> /// <param name="writingJsonLight">true if we're writing JSON lite, false if we're writing verbose JSON.</param> private static void WriteError(IJsonWriter jsonWriter, string code, string message, ODataInnerError innerError, IEnumerable<ODataInstanceAnnotation> instanceAnnotations, Action<IEnumerable<ODataInstanceAnnotation>> writeInstanceAnnotationsDelegate, int maxInnerErrorDepth, bool writingJsonLight) { Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(code != null, "code != null"); Debug.Assert(message != null, "message != null"); Debug.Assert(instanceAnnotations != null, "instanceAnnotations != null"); // "error": { jsonWriter.StartObjectScope(); if (writingJsonLight) { jsonWriter.WriteName(JsonLightConstants.ODataErrorPropertyName); } else { jsonWriter.WriteName(JsonConstants.ODataErrorName); } jsonWriter.StartObjectScope(); // "code": "<code>" jsonWriter.WriteName(JsonConstants.ODataErrorCodeName); jsonWriter.WriteValue(code); // "message": "<message string>" jsonWriter.WriteName(JsonConstants.ODataErrorMessageName); jsonWriter.WriteValue(message); if (innerError != null) { WriteInnerError(jsonWriter, innerError, JsonConstants.ODataErrorInnerErrorName, /* recursionDepth */ 0, maxInnerErrorDepth); } if (writingJsonLight) { Debug.Assert(writeInstanceAnnotationsDelegate != null, "writeInstanceAnnotations != null"); writeInstanceAnnotationsDelegate(instanceAnnotations); } // } } jsonWriter.EndObjectScope(); jsonWriter.EndObjectScope(); }
/// <summary> /// Reads an inner error payload. /// </summary> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <returns>An <see cref="ODataInnerError"/> representing the read inner error.</returns> /// <remarks> /// Pre-Condition: any - will throw if not StartObject /// Post-Condition: JsonNodeType.Property - The next property in the error value /// JsonNodeType.EndObject - The end of the error value /// </remarks> private ODataInnerError ReadInnerError(int recursionDepth) { Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "JsonReader.DisableInStreamErrorDetection"); this.JsonReader.AssertNotBuffering(); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.MessageReaderSettings.MessageQuotas.MaxNestingDepth); this.JsonReader.ReadStartObject(); ODataInnerError innerError = new ODataInnerError(); ODataJsonReaderUtils.ErrorPropertyBitMask propertiesFoundBitField = ODataJsonReaderUtils.ErrorPropertyBitMask.None; while (this.JsonReader.NodeType == JsonNodeType.Property) { string propertyName = this.JsonReader.ReadPropertyName(); switch (propertyName) { case JsonConstants.ODataErrorInnerErrorMessageName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.MessageValue, JsonConstants.ODataErrorInnerErrorMessageName); innerError.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorMessageName); break; case JsonConstants.ODataErrorInnerErrorTypeNameName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.TypeName, JsonConstants.ODataErrorInnerErrorTypeNameName); innerError.TypeName = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorTypeNameName); break; case JsonConstants.ODataErrorInnerErrorStackTraceName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.StackTrace, JsonConstants.ODataErrorInnerErrorStackTraceName); innerError.StackTrace = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorInnerErrorStackTraceName); break; case JsonConstants.ODataErrorInnerErrorInnerErrorName: ODataJsonReaderUtils.VerifyErrorPropertyNotFound( ref propertiesFoundBitField, ODataJsonReaderUtils.ErrorPropertyBitMask.InnerError, JsonConstants.ODataErrorInnerErrorInnerErrorName); innerError.InnerError = this.ReadInnerError(recursionDepth); break; default: // skip any unsupported properties in the inner error this.JsonReader.SkipValue(); break; } } this.JsonReader.ReadEndObject(); this.JsonReader.AssertNotBuffering(); return innerError; }
/// <summary> /// Reads the content of an inner error element. /// </summary> /// <param name="xmlReader">The (buffering) Xml reader to read the error payload from.</param> /// <param name="recursionDepth">The number of times this function has been called recursively.</param> /// <param name="maxInnerErrorDepth">The maximumum number of recursive internalexception elements to allow.</param> /// <returns>The <see cref="ODataInnerError"/> representing the inner error.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - the m:innererror or m:internalexception element /// Post-Condition: Any - the node after the m:innererror/m:internalexception end element or the node after the empty m:innererror/m:internalexception element node. /// </remarks> private static ODataInnerError ReadInnerErrorElement(BufferingXmlReader xmlReader, int recursionDepth, int maxInnerErrorDepth) { Debug.Assert(xmlReader != null, "this.XmlReader != null"); Debug.Assert(xmlReader.NodeType == XmlNodeType.Element, "xmlReader.NodeType == XmlNodeType.Element"); Debug.Assert( xmlReader.LocalName == AtomConstants.ODataInnerErrorElementName || xmlReader.LocalName == AtomConstants.ODataInnerErrorInnerErrorElementName, "Expected reader to be positioned on 'm:innererror' or 'm:internalexception' element."); Debug.Assert(xmlReader.NamespaceEquals(xmlReader.ODataMetadataNamespace), "this.XmlReader.NamespaceEquals(this.ODataMetadataNamespace)"); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, maxInnerErrorDepth); ODataInnerError innerError = new ODataInnerError(); DuplicateInnerErrorElementPropertyBitMask elementsReadBitmask = DuplicateInnerErrorElementPropertyBitMask.None; if (!xmlReader.IsEmptyElement) { // Move to the first child node of the element. xmlReader.Read(); do { switch (xmlReader.NodeType) { case XmlNodeType.EndElement: // end of the <m:innererror> or <m:internalexception> element continue; case XmlNodeType.Element: if (xmlReader.NamespaceEquals(xmlReader.ODataMetadataNamespace)) { switch (xmlReader.LocalName) { // <m:message> case AtomConstants.ODataInnerErrorMessageElementName: VerifyInnerErrorElementNotFound( ref elementsReadBitmask, DuplicateInnerErrorElementPropertyBitMask.Message, AtomConstants.ODataInnerErrorMessageElementName); innerError.Message = xmlReader.ReadElementValue(); continue; // <m:type> case AtomConstants.ODataInnerErrorTypeElementName: VerifyInnerErrorElementNotFound( ref elementsReadBitmask, DuplicateInnerErrorElementPropertyBitMask.TypeName, AtomConstants.ODataInnerErrorTypeElementName); innerError.TypeName = xmlReader.ReadElementValue(); continue; // <m:stacktrace> case AtomConstants.ODataInnerErrorStackTraceElementName: VerifyInnerErrorElementNotFound( ref elementsReadBitmask, DuplicateInnerErrorElementPropertyBitMask.StackTrace, AtomConstants.ODataInnerErrorStackTraceElementName); innerError.StackTrace = xmlReader.ReadElementValue(); continue; // <m:internalexception> case AtomConstants.ODataInnerErrorInnerErrorElementName: VerifyInnerErrorElementNotFound( ref elementsReadBitmask, DuplicateInnerErrorElementPropertyBitMask.InternalException, AtomConstants.ODataInnerErrorInnerErrorElementName); innerError.InnerError = ReadInnerErrorElement(xmlReader, recursionDepth, maxInnerErrorDepth); continue; default: break; } } break; default: break; } xmlReader.Skip(); } while (xmlReader.NodeType != XmlNodeType.EndElement); } // Read over the end element, or empty start element. xmlReader.Read(); return innerError; }
/// <summary> /// Try to read an inner error property value. /// </summary> /// <param name="innerError">An <see cref="ODataInnerError"/> instance that was read from the reader or null if none could be read.</param> /// <param name="recursionDepth">The number of times this method has been called recursively.</param> /// <returns>true if an <see cref="ODataInnerError"/> instance that was read; otherwise false.</returns> private bool TryReadInnerErrorPropertyValue(out ODataInnerError innerError, int recursionDepth) { Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.Property, "this.currentBufferedNode.NodeType == JsonNodeType.Property"); Debug.Assert(this.parsingInStreamError, "this.parsingInStreamError"); this.AssertBuffering(); ValidationUtils.IncreaseAndValidateRecursionDepth(ref recursionDepth, this.maxInnerErrorDepth); // move the reader onto the property value this.ReadInternal(); // we expect a start-object node here if (this.currentBufferedNode.NodeType != JsonNodeType.StartObject) { innerError = null; return false; } // read the start-object node this.ReadInternal(); innerError = new ODataInnerError(); // we expect one of the supported properties for the value (or end-object) ODataJsonLightReaderUtils.ErrorPropertyBitMask propertiesFoundBitmask = ODataJsonLightReaderUtils.ErrorPropertyBitMask.None; while (this.currentBufferedNode.NodeType == JsonNodeType.Property) { // NOTE the Json reader already ensures that the value of a property node is a string string propertyName = (string)this.currentBufferedNode.Value; switch (propertyName) { case JsonConstants.ODataErrorInnerErrorMessageName: if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.MessageValue)) { return false; } string message; if (this.TryReadErrorStringPropertyValue(out message)) { innerError.Message = message; } else { return false; } break; case JsonConstants.ODataErrorInnerErrorTypeNameName: if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.TypeName)) { return false; } string typeName; if (this.TryReadErrorStringPropertyValue(out typeName)) { innerError.TypeName = typeName; } else { return false; } break; case JsonConstants.ODataErrorInnerErrorStackTraceName: if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.StackTrace)) { return false; } string stackTrace; if (this.TryReadErrorStringPropertyValue(out stackTrace)) { innerError.StackTrace = stackTrace; } else { return false; } break; case JsonConstants.ODataErrorInnerErrorInnerErrorName: if (!ODataJsonLightReaderUtils.ErrorPropertyNotFound(ref propertiesFoundBitmask, ODataJsonLightReaderUtils.ErrorPropertyBitMask.InnerError)) { return false; } ODataInnerError nestedInnerError; if (this.TryReadInnerErrorPropertyValue(out nestedInnerError, recursionDepth)) { innerError.InnerError = nestedInnerError; } else { return false; } break; default: // if we find a non-supported property in an inner error, we skip it this.SkipValueInternal(); break; } this.ReadInternal(); } Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.EndObject, "this.currentBufferedNode.NodeType == JsonNodeType.EndObject"); return true; }