Exemplo n.º 1
0
        /// <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));
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
        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;
            }
        }
Exemplo n.º 8
0
        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;
            }
        }
Exemplo n.º 10
0
        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);
        }
Exemplo n.º 11
0
        /// <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);
            }
        }
Exemplo n.º 12
0
        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'.");
        }
Exemplo n.º 13
0
        /// <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);
            }
        }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
0
            /// <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);
        }
Exemplo n.º 17
0
        /// <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);
        }
Exemplo n.º 19
0
        /// <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());
        }
Exemplo n.º 21
0
        /// <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);
        }
Exemplo n.º 23
0
        /// <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);
        }
Exemplo n.º 24
0
 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();
 }
Exemplo n.º 25
0
        /// <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();
        }
Exemplo n.º 26
0
        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;
            }
        }
Exemplo n.º 28
0
        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.");
        }
Exemplo n.º 29
0
        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'.");
        }
Exemplo n.º 30
0
        /// <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;
        }
Exemplo n.º 33
0
        /// <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();
        }
Exemplo n.º 34
0
        /// <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();
        }
Exemplo n.º 35
0
        /// <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;
        }
Exemplo n.º 38
0
        /// <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;
        }
        /// <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;
            }
        }