0

I am using jQuery $.post to post some data to an ActionResult method inside my controller. When an error is thrown in the controller, it should return the error message within the responseText of the response but it's not working.

The post request is hitting the controller.

The callback function fail seems to be triggered. Just not getting the error message returned. Not sure what I am doing wrong?

This is jQuery posting data:

var postData = ["1","2","3"];

$.post('/MyController/GetSomething', $.param(postData, true))
      .done(function (data) {
              alert('Done!');                        
      })
      .fail(function (xhr, textStatus, errorThrown) {
              alert(xhr.responseText); //xhr.responseText is empty   
      });
 });

Controllers


    public class MyController : BaseController
    {
        public ActionResult GetSomething(List ids)
        {
            try
            {
                GetSomeData(ids);
            }
            catch (Exception ex)
            {
                return ThrowJsonError(new Exception(String.Format("The following error occurred: {0}", ex.ToString())));
            }

            return RedirectToAction("Index");
        }
    }

    public class BaseController : Controller
    {
        public JsonResult ThrowJsonError(Exception ex)
        {
            Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
            Response.StatusDescription = ex.Message;

            return Json(new { Message = ex.Message }, JsonRequestBehavior.AllowGet);
        }
    }


Update What's interesting is that if I move some of the logic from out of the BaseController and into the MyController, I am able to get the desired result.

Why would this happen?

public class MyController : BaseController
    {
        public ActionResult GetSomething(List<string> ids)
        {
            try
            {
                GetSomeData(ids);
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
                Response.StatusDescription = ex.Message;

                return Json(new { Message = ex.Message }, JsonRequestBehavior.AllowGet);
            }

            return RedirectToAction("Index");
        }
    }
9
  • Does it reach to the controller or gives an error before? Commented Sep 29, 2016 at 17:20
  • Yes, it does reach the controller. If an exception is then thrown in the Controller then the Message doesn't come back as xhr.ResponseText = "" Commented Sep 29, 2016 at 17:28
  • if you put alert(data.Message); before alert('Done!'); what happend? Commented Sep 29, 2016 at 17:28
  • I've some question here, what is in GetSomeData(ids); after this you redirect to index action, what is in Index and you had not passed any data from GetSomething to index Commented Sep 29, 2016 at 17:33
  • @DanielVorph When the exception is thrown in the Controller, I am definitely hitting the .fail(function (xhr, textStatus, errorThrown) { alert(xhr.responseText); //xhr.responseText is empty }); function. Commented Sep 29, 2016 at 17:33

1 Answer 1

2

This is occurring because you have an invalid StatusDescription being set in the ThrowJsonError function. It has line feed characters which cause unexpected results in an Http Header. See this related question

The issue is being obfuscated because your first example has you set the StatusDescription to the Message property of a new Exception you are constructing which will contain line feeds and stack trace info because you call ex.ToString(). The second one works because you are just setting the StatusDescription to ex.Message and that doesn't contain problematic characters

To be safe, you probably should just use a relatively benign StatusDescription since you don't really need it for anything anyway (you can get the Message in the fail() either way.

Note the following code works (still do not recommend it):

public ActionResult ThrowJsonError(Exception ex)
{
   Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
   Response.StatusDescription = ex.Message; // does not work
   Response.StatusDescription = ex.Message.Replace('\r', ' ').Replace('\n', ' '); // works

   return Json(new { Message = ex.Message }, JsonRequestBehavior.AllowGet);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Ah understood. Thank you for helping and taking the time to explain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.