/// <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> /// 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> /// Reads a property value which occurs in the "error" object scope. /// </summary> /// <param name="error">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> /// <param name="duplicationPropertyNameChecker">DuplicatePropertyNamesChecker to use for extracting property annotations /// targetting any custom instance annotations on the error.</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 "error" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private void ReadPropertyValueInODataErrorObject(ODataError error, string propertyName, DuplicatePropertyNamesChecker duplicationPropertyNameChecker) { switch (propertyName) { case JsonConstants.ODataErrorCodeName: error.ErrorCode = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorCodeName); break; case JsonConstants.ODataErrorMessageName: error.Message = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorMessageName); break; case JsonConstants.ODataErrorTargetName: error.Target = this.JsonReader.ReadStringValue(JsonConstants.ODataErrorTargetName); break; case JsonConstants.ODataErrorDetailsName: error.Details = this.ReadDetails(); break; case JsonConstants.ODataErrorInnerErrorName: error.InnerError = this.ReadInnerError(0 /* recursionDepth */); break; default: // See if it's an instance annotation if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName)) { ODataJsonLightPropertyAndValueDeserializer valueDeserializer = new ODataJsonLightPropertyAndValueDeserializer(this.JsonLightInputContext); object typeName = null; var odataAnnotations = duplicationPropertyNameChecker.GetODataPropertyAnnotations(propertyName); if (odataAnnotations != null) { odataAnnotations.TryGetValue(ODataAnnotationNames.ODataType, out typeName); } var value = valueDeserializer.ReadNonEntityValue( typeName as string, null /*expectedValueTypeReference*/, null /*duplicatePropertiesNamesChecker*/, null /*collectionValidator*/, false /*validateNullValue*/, false /*isTopLevelPropertyValue*/, false /*insideComplexValue*/, propertyName); error.GetInstanceAnnotations().Add(new ODataInstanceAnnotation(propertyName, value.ToODataValue())); } else { // we only allow a 'code', 'message', 'target', 'details, and 'innererror' properties // in the value of the 'error' property or custom instance annotations throw new ODataException(Strings.ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty(propertyName)); } break; } }
/// <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<IEnumerable<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, innerError, error.GetInstanceAnnotations(), writeInstanceAnnotationsDelegate, maxInnerErrorDepth, writingJsonLight); }
/// <summary> /// Asynchronously reads a property value which occurs in the "error" object scope. /// </summary> /// <param name="error">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> /// <param name="duplicationPropertyNameChecker"><see cref="PropertyAndAnnotationCollector"/> to use for extracting property annotations /// targeting any custom instance annotations on the error.</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 "error" object. /// any - Anything else after the property value is an invalid payload (but won't fail in this method). /// </remarks> private async Task ReadPropertyValueInODataErrorObjectAsync(ODataError error, string propertyName, PropertyAndAnnotationCollector duplicationPropertyNameChecker) { switch (propertyName) { case JsonConstants.ODataErrorCodeName: error.ErrorCode = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorCodeName) .ConfigureAwait(false); break; case JsonConstants.ODataErrorMessageName: error.Message = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorMessageName) .ConfigureAwait(false); break; case JsonConstants.ODataErrorTargetName: error.Target = await this.JsonReader.ReadStringValueAsync(JsonConstants.ODataErrorTargetName) .ConfigureAwait(false); break; case JsonConstants.ODataErrorDetailsName: error.Details = await this.ReadErrorDetailsAsync() .ConfigureAwait(false); break; case JsonConstants.ODataErrorInnerErrorName: error.InnerError = await this.ReadInnerErrorAsync(recursionDepth : 0) .ConfigureAwait(false); break; default: // See if it's an instance annotation if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName)) { ODataJsonLightPropertyAndValueDeserializer propertyAndValueDeserializer = new ODataJsonLightPropertyAndValueDeserializer(this.JsonLightInputContext); object typeName; duplicationPropertyNameChecker.GetODataPropertyAnnotations(propertyName).TryGetValue(ODataAnnotationNames.ODataType, out typeName); var value = await propertyAndValueDeserializer.ReadNonEntityValueAsync( payloadTypeName : typeName as string, expectedValueTypeReference : null, propertyAndAnnotationCollector : null, collectionValidator : null, validateNullValue : false, isTopLevelPropertyValue : false, insideResourceValue : false, propertyName : propertyName).ConfigureAwait(false); error.GetInstanceAnnotations().Add(new ODataInstanceAnnotation(propertyName, value.ToODataValue())); } else { // We only allow a 'code', 'message', 'target', 'details, and 'innererror' properties // in the value of the 'error' property or custom instance annotations throw new ODataException(Strings.ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty(propertyName)); } break; } }