private static string GetErrorMessage(DataServiceClientException exception, string contentType) { string errorMessage = string.Empty; if (contentType.StartsWith(MimeTypes.ApplicationAtomXml, StringComparison.OrdinalIgnoreCase) || contentType.StartsWith(MimeTypes.ApplicationXml, StringComparison.OrdinalIgnoreCase)) { var xelement = XElement.Parse(exception.Message); var innerError = xelement.Element(xelement.Name.Namespace.GetName("innererror")); if (innerError != null) { errorMessage = innerError.Element(innerError.Name.Namespace.GetName("message")).Value; } else { errorMessage = xelement.Element(xelement.Name.Namespace.GetName("message")).Value; } } else if (contentType.StartsWith(MimeTypes.ApplicationJsonLight, StringComparison.OrdinalIgnoreCase)) { JObject jsonObject = JObject.Parse(exception.Message); var innerError = jsonObject["error"]["innererror"]; if (innerError != null) { errorMessage = ((JValue)innerError["message"]).Value as string; } else { errorMessage = ((JValue)jsonObject["error"]["message"]).Value as string; } } ExceptionUtilities.Assert(!string.IsNullOrEmpty(errorMessage), "Unsupported content type value: " + contentType); return errorMessage; }
/// <summary> /// Ends an asynchronous request to an Internet resource. /// </summary> /// <typeparam name="TElement">Element type of the result.</typeparam> /// <param name="source">Source object of async request.</param> /// <param name="context">The data service context.</param> /// <param name="method">async method name.</param> /// <param name="asyncResult">The asyncResult being ended.</param> /// <returns>The response - result of the request.</returns> internal static IEnumerable <TElement> EndExecute <TElement>(object source, DataServiceContext context, string method, IAsyncResult asyncResult) { QueryResult result = null; try { result = QueryResult.EndExecuteQuery <TElement>(source, method, asyncResult); return(result.ProcessResult <TElement>(result.ServiceRequest.Plan)); } catch (DataServiceQueryException ex) { Exception inEx = ex; while (inEx.InnerException != null) { inEx = inEx.InnerException; } DataServiceClientException serviceEx = inEx as DataServiceClientException; if (context.IgnoreResourceNotFoundException && serviceEx != null && serviceEx.StatusCode == (int)HttpStatusCode.NotFound) { QueryOperationResponse qor = new QueryOperationResponse <TElement>(ex.Response.HeaderCollection, ex.Response.Query, MaterializeAtom.EmptyResults); qor.StatusCode = (int)HttpStatusCode.NotFound; return((IEnumerable <TElement>)qor); } throw; } }
/// <summary>operation with exception</summary> /// <param name="e">exception object</param> /// <param name="response">response object</param> private void HandleOperationException(InvalidOperationException e, IODataResponseMessage response) { Debug.Assert(this.entryIndex >= 0 && this.entryIndex < this.ChangedEntries.Count, string.Format(System.Globalization.CultureInfo.InvariantCulture, "this.entryIndex = '{0}', this.ChangedEntries.Count = '{1}'", this.entryIndex, this.ChangedEntries.Count)); Descriptor current = this.ChangedEntries[this.entryIndex]; HeaderCollection headers = null; HttpStatusCode statusCode = HttpStatusCode.InternalServerError; Version responseVersion = null; if (response != null) { headers = new HeaderCollection(response); statusCode = (HttpStatusCode)response.StatusCode; this.HandleOperationResponseHeaders(statusCode, headers); e = BaseSaveResult.HandleResponse( this.RequestInfo, statusCode, response.GetHeader(XmlConstants.HttpODataVersion), response.GetStream, false /*throwOnFailure*/, out responseVersion); } else { headers = new HeaderCollection(); headers.SetHeader(XmlConstants.HttpContentType, XmlConstants.MimeTextPlain); // In V2 we used to merge individual responses from a call to SaveChanges() into a single batch response payload and then process that. // When we encounter an exception at this point in V2, we used to write the exception to the batch response payload and later on when we // process through the batch response, we create a DataServiceClientException for each failed operation. // For backcompat reason, we will always convert the exception type to DataServiceClientException here. Debug.Assert(e != null, "e != null"); if (e.GetType() != typeof(DataServiceClientException)) { e = new DataServiceClientException(e.Message, e); } } // For error scenarios, we never invoke the ReadingEntity event. this.cachedResponses.Add(new CachedResponse(current, headers, statusCode, responseVersion, null, e)); this.perRequest = null; this.CheckContinueOnError(); }
public void When_DataServiceClientException_is_serialized_all_instance_data_is_saved() { // Arrange const string expectedMessage = "Custom message"; const int expectedStatusCode = 705; var sut = new DataServiceClientException(expectedMessage, expectedStatusCode); var bf = new BinaryFormatter(); var stream = new MemoryStream(); // Act bf.Serialize(stream, sut); stream.Seek(0, SeekOrigin.Begin); var ds = (DataServiceClientException)bf.Deserialize(stream); // Assert Assert.AreEqual(expectedMessage, ds.Message); Assert.AreEqual(expectedStatusCode, ds.StatusCode); }
/// <summary> /// execute uri and materialize result /// </summary> /// <typeparam name="TElement">element type</typeparam> /// <param name="context">context</param> /// <param name="queryComponents">query components for request to execute</param> /// <returns>enumerable of results</returns> internal QueryOperationResponse <TElement> Execute <TElement>(DataServiceContext context, QueryComponents queryComponents) { QueryResult result = null; try { Uri requestUri = queryComponents.Uri; DataServiceRequest <TElement> serviceRequest = new DataServiceRequest <TElement>(requestUri, queryComponents, this.Plan); result = serviceRequest.CreateExecuteResult(this, context, null, null, Util.ExecuteMethodName); result.ExecuteQuery(); return(result.ProcessResult <TElement>(this.Plan)); } catch (InvalidOperationException ex) { if (result != null) { QueryOperationResponse operationResponse = result.GetResponse <TElement>(MaterializeAtom.EmptyResults); if (null != operationResponse) { if (context.IgnoreResourceNotFoundException) { DataServiceClientException cex = ex as DataServiceClientException; if (cex != null && cex.StatusCode == (int)HttpStatusCode.NotFound) { // don't throw return((QueryOperationResponse <TElement>)operationResponse); } } operationResponse.Error = ex; throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, operationResponse); } } throw; } }
/// <summary>operation with exception</summary> /// <param name="e">exception object</param> /// <param name="response">response object</param> private void HandleOperationException(InvalidOperationException e, IODataResponseMessage response) { Debug.Assert(this.entryIndex >= 0 && this.entryIndex < this.ChangedEntries.Count(), string.Format(System.Globalization.CultureInfo.InvariantCulture, "this.entryIndex = '{0}', this.ChangedEntries.Count = '{1}'", this.entryIndex, this.ChangedEntries.Count())); Descriptor current = this.ChangedEntries[this.entryIndex]; HeaderCollection headers = null; HttpStatusCode statusCode = HttpStatusCode.InternalServerError; Version responseVersion = null; if (null != response) { headers = new HeaderCollection(response); statusCode = (HttpStatusCode)response.StatusCode; this.HandleOperationResponseHeaders(statusCode, headers); e = BaseSaveResult.HandleResponse( this.RequestInfo, statusCode, response.GetHeader(XmlConstants.HttpODataVersion), response.GetStream, false/*throwOnFailure*/, out responseVersion); } else { headers = new HeaderCollection(); headers.SetHeader(XmlConstants.HttpContentType, XmlConstants.MimeTextPlain); // In V2 we used to merge individual responses from a call to SaveChanges() into a single batch response payload and then process that. // When we encounter an exception at this point in V2, we used to write the exception to the batch response payload and later on when we // process through the batch response, we create a DataServiceClientException for each failed operation. // For backcompat reason, we will always convert the exception type to DataServiceClientException here. Debug.Assert(e != null, "e != null"); if (e.GetType() != typeof(DataServiceClientException)) { e = new DataServiceClientException(e.Message, e); } } // For error scenarios, we never invoke the ReadingEntity event. this.cachedResponses.Add(new CachedResponse(current, headers, statusCode, responseVersion, null, e)); this.perRequest = null; this.CheckContinueOnError(); }