We recently upgraded from Syncfusion version 27.1.48 to 28.2.7.
The grid integrates with an Odata api that occasionally returns 400 responses, and we noticed a difference in the way that errors are returned between these two versions of Syncfusion. Previously, a 400 http response would result in the OnActionFailure event of the grid firing and the error field of the FailureEventArgs argument would contain the actual response body of the 400 response. We relied on this behaviour to display user-related error messages.
Starting with version 28.2.7 however, instead the message contains the string "E is an invalid start of value" and the stack trace indicates that this is thrown during JSON parsing.
Is this an intentional change? If so, what is the alternative? How can I intercept a non-200 odata response from the api and extract the response message from it?
Thanks,
Ronan
Hi Ronan van de Vyver,
Based on the requirements, if you want to catch error details and handle failures, please note that if you only get a standard exception in the catch block to return error messages, we support sending exceptions directly. This allows them to be processed in the ProcessResponse method. For authentication failures, we suggest using the ProcessResponse method by sending exceptions directly as like in the below example.
Code Snippet:
|
protected override void OnAfterRender(bool firstRender) { if (firstRender) { DataManager.DataAdaptor = new NewODataClass(DataManager); } base.OnAfterRender(firstRender); }
public class NewODataClass : ODataV4Adaptor { public NewODataClass(DataManager dm) : base(dm) {
}
public override object ProcessQuery(DataManagerRequest queries) { RequestOptions ActualReturnValue = (RequestOptions)(base.ProcessQuery(queries)); //you can customize the query here Console.WriteLine(ActualReturnValue.Url); Console.WriteLine(ActualReturnValue.BaseUrl); return ActualReturnValue; }
public override async Task<object> ProcessResponse<T>(object data, DataManagerRequest queries) { HttpResponseMessage responseval = data as HttpResponseMessage; if (data is HttpResponseMessage response) { // Check for error status codes if (!response.IsSuccessStatusCode) { string errorMessage = await response.Content.ReadAsStringAsync(); // Log the error or handle it accordingly // You can throw an exception or handle it based on your application's needs throw new HttpRequestException($"Error: {response.StatusCode} - {errorMessage}"); } }
//you can customize the response here var ActualReturnValue = await base.ProcessResponse<T>(data, queries); return ActualReturnValue; } } |
We have attached the concern sample, please check and get back to us if you have any concerns.
Regards,
Sanjay Kumar Suresh
I have implemented your suggestion and found that the exception, when caught, is actually two exceptions wrapped together and then converted to string. So the actual 400 error is embedded somewhere inside another exception. By overriding the Adaptor's ProcessResponse method I can extract the http response, basically by searching the string for "Response body:". While this is functional, it is a bit janky.
Is there no way to get the original http response body directly?
Thanks,
Ronan
Facing the similar issue using Syncfusion.Blazor.Grid 30.1.37, I have implementing the proposed workaround.
Unfortunately, "ProcessResponse" is not called when doing insert / update and the 400 http response goes through leading to the "E is an invalid start of value".
- Should "ProcessResponse" be called for all queries?
- Is there a better way to handle odata error message?
- Is it possible to fix the regression introduced from 28.2.7?
Hi Vincent Bray,
We would like to inform you that when loading data on the grid, if you want to catch error details and handle failures, please note that if you only get a standard exception in the catch block to return error messages, we support sending exceptions directly. This allows them to be processed in the ProcessResponse method. For CRUD operation failures, you will need to use the ProcessCrudResponse method by sending exceptions directly, which allows them to be processed. Please refer to the code snippet and sample provided below for your reference. This is a possible way to obtain detailed error information using the OnActionFailure event.
|
public override async Task<object> ProcessCrudResponse<T>(object data, DataManagerRequest queries) { if (data is HttpResponseMessage response) { // Check for error status codes if (!response.IsSuccessStatusCode) { string errorMessage = await response.Content.ReadAsStringAsync(); Console.WriteLine($"HTTP Error: {response.StatusCode}"); Console.WriteLine($"Response Message: {errorMessage}");
// Throw a detailed exception throw new HttpRequestException($"Error: {response.StatusCode} - {errorMessage}"); } } // Process successful response var ActualReturnValue = await base.ProcessResponse<T>(data, queries); return ActualReturnValue;
} |
|
|
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/DatagridOdatav4Sample
Additional reference: Manage
Exception ActionFailure | Syncfusion Forum Assist
Regards,
Sanjay Kumar Suresh
Hi Sanjay,
It looks like you are generating an HttpRequestException when calling "EnsureSuccessStatusCode" from the "
SendRequest" function (ref below). We should receive the original response content coming from the server.
It looks like a bug to me
public override async Task<object> ProcessCrudResponse<T>(object data, DataManagerRequest queries)
{
if (data is HttpResponseMessage response)
{
// Check for error status codes
if (!response.IsSuccessStatusCode)
{
var errorMessage = await response.Content.ReadAsStringAsync();
throw new HttpRequestException($"{errorMessage}");
}
}
var ActualReturnValue = base.ProcessCrudResponse<T>(data, queries);
return ActualReturnValue;
}
errorMessage content:
'Error: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at Syncfusion.Blazor.Data.HttpHandler.SendRequest(HttpRequestMessage data). Response content: "Price overlap with existing price"'
Hi Vincent Bray,
We
would like to inform you that various types of exceptions can be thrown from
the server side. Please refer to the different types of exceptions in the link
provided below. Handling each exception type with separate logic might not
always be feasible. Instead, we manage them using a global exception handler
that captures the exceptions and returns their details. If there are any
additional details you expect us to provide regarding these exceptions, please
let us know, and we will evaluate the feasibility of implementing them on our
end.
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/using-standard-exception-types
Regards,
Sanjay Kumar Suresh