Handling errors in grid where status is not 200

5 posts, 1 answers
  1. Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 06 Jun 2013 Link to this post

    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.
  2. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 10 Jun 2013 Link to this post

    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!
  3. Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 12 Jun 2013 Link to this post

    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.



  4. Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 12 Jun 2013 Link to this post

    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.
  5. Answer
    Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 14 Jun 2013 Link to this post

    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.
Back to Top