This is a migrated thread and some comments may be shown as answers.

Handling errors in grid where status is not 200

4 Answers 484 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Jon Smith
Top achievements
Rank 1
Jon Smith asked on 06 Jun 2013, 11:04 AM
Hi,
I have put in a general error handling to handle exceptions and authorisation errors for all Ajax calls, both Kendo and my api. I send back status 500 of exception and 401, Forbidden, or 403, Unauthorized, for authorisation errors.

The problem is I do not seem to be able to prevent the dataSource from updating the display if I get a non-200, OK, response. Looking at the code in Chrome it does not call the function associated with 'databinding' on line 13 of the code below.
01.function kendoGridErrorHandler(args) {
02.    if (args.errors == undefined) {
03.        if (args.xhr.status == 403) {
04.            updatePrimaryMessage("You are not authorised to carry out that operation.", true);
05.        } else if (args.xhr.status == 401) {
06.            updatePrimaryMessage("You need to be logged in to carry out that operation.", true);
07.        } else if (args.xhr.status == 500) {
08.            updatePrimaryMessage("The operation did not complete because of an error.", true);
09.        } else {
10.            updatePrimaryMessage("There was problem. Please refresh the screen.", true);
11.        }
12.        $('#PrimaryKGrid').data().kendoGrid.one('dataBinding', function(e) {
13.            e.preventDefault();
14.        });
15.    } else {
16.        //error means Ajax error response. customerror means Kendo error response
17.        var grid = $('#PrimaryKGrid').data("kendoGrid");
18.        grid.one("dataBinding", function(e) {
19.            e.preventDefault(); // cancel grid rebind if error occurs
20.            //We have formatted errors to display
21.            for (var error in args.errors) {
22.                showMessage(grid.editable.element, error, args.errors[error].errors);
23.            }
24.        });
25.    }
26.}
Can you suggest what I have done wrong?

Thanks in advance.

4 Answers, 1 is accepted

Sort by
0
Petur Subev
Telerik team
answered on 10 Jun 2013, 07:39 AM
Hello Jon,

Your code looks valid and we do not see any potential reason to prevent the Grid from rebinding. Please consider submitting a sample project which demonstrates the case. As a base you can use the project from here.

Kind Regards,
Petur Subev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Jon Smith
Top achievements
Rank 1
answered on 12 Jun 2013, 04:16 PM
I have produced an edited copy of the 'Handling server-side validation errors during pop-up editing' application (note: I could not attach it here because it was over 2Mb). I have extended your example to handle a number of issues not handled in the original. They are:

  • Exceptions inside MVC do not work well with Ajax calls. I have therefore created a Exception Filter which returns a status 500, internal server error, return. I have added code to display a message in a div above the grid. (The AjaxExpectionAttribute is added to the GlobalFilters in Global.asax.cs).
  • I have also extended this to handle authorisation errors, although the code needed to catch this in the authorise part of MVC is not present in your example application. The code returns a 401 or 403 status return to indicate the type of error encountered.
  • Your version doesn't handle ModelErrors where the property field is empty. This is a valid MVC validation error return and is used in cases where the error does not relate to a particular property. Such an error is displayed in the div above the grid.
  • I also take the opportunity to return a success message if the ajax call returns one. This is returned in the div too, but without the field-validation-error class.
That explains what I have done. However it doesn't work properly because on a non-200 status call it fails to call preventDefault() (see line 91 of Index.cshtml). I am not clear why this doesn't work and I would appreciate you help on this.

Note also I have changed your original PopUp editing to lnLine editing as that is how my application works.



0
Jon Smith
Top achievements
Rank 1
answered on 12 Jun 2013, 04:18 PM
I have produced an edited copy of the 'Handling server-side validation
errors during pop-up editing' application (note: I could not attach it
here because it was over 2Mb). I have therefore appended it to the support ticket.
0
Accepted
Jon Smith
Top achievements
Rank 1
answered on 14 Jun 2013, 10:08 AM
With the help of Telerik I have fixed this problem. I didn't realise that if the returned json data contained the property "errors" in it then it automatically picks that up and considers it as an error. However, because I was returning either empty data or json without errors property in it this was not happening.

The answer is to to call cancelChanges on the grid data, i.e.
$('#YourGridName').data("kendoGrid").cancelChanges();
In my original code in the first post of this thread the line given above, i.e. calling cancelChanges should replace lines 12 and 13.

For my code to work you will also need a ExceptionFilter to catch exceptions in Ajax calls. see below for example exception filter:

public class AjaxExceptionAttribute : FilterAttribute, IExceptionFilter
{
 
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled ||
            !filterContext.HttpContext.Request.IsAjaxRequest()) return;
 
        //its an Ajax exception so send a Ajax response
        filterContext.Result =
            new HttpStatusCodeResult( (int)HttpStatusCode.InternalServerError);
 
        //These two are needed to stop the error being handled by elmah or IIS
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        filterContext.ExceptionHandled = true;
    }
}
and also code in your login path to catch authorisation errors. Example code below:
public virtual ActionResult Login()
{
    if (Request.IsAjaxRequest())
    {
        // if the user is authenticated, then this is not-authorized (403),
        //   otherwise this is not-authenticated (401)
        Response.StatusCode = (Request.IsAuthenticated) ? 403 : 401;
 
        return Json(
            // return the url that the client should redirect to
            new { Url = Request.Url },
            // allow this GET to return a json string
            JsonRequestBehavior.AllowGet);
    }
             
     //...otherwise carry on with normal user login process

I hope this helps others in providing much more robust error handling for Kendo grids.
Tags
Grid
Asked by
Jon Smith
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
Jon Smith
Top achievements
Rank 1
Share this question
or