Search code examples
c#asp.netasp.net-mvchttpclienthttpresponsemessage

ASP.NET send exception message


I'm developing web application and here is how I handle exceptions:

void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    LogManager.GetCurrentClassLogger().Error(ex);
    Response.Clear();
    Server.ClearError();

    HttpException httpEx = ex as HttpException;

    if (httpEx == null)
        httpEx = new HttpException(400, ex.Message, ex);

    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Handler");
    routeData.Values.Add("exception", httpEx);
    Response.TrySkipIisCustomErrors = true;
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    var c = ControllerBuilder.Current.GetControllerFactory().CreateController(rc, "Error");
    c.Execute(rc);
}

When an Exception occurs (ex: throw new ArgumentException("Generator with given Id does not exist.");) user receive Error view with details about what happened.

The problem is, the error message is not sent to the user in HttpResponseMessage (as ReasonPhrase or anything else).

private async void DeleteGenerator(Guid id)
{
    var response = await dataService.RemoveGenerator(id);
    if ((int)response.StatusCode >= 300)
        MessageBox.Show( /* Error message from response */ );  
}

Here I should receive box with "Generator with given [...]" in it, but I have no clue how to achieve that. I've tried this but the "HttpError" is missing, this but I really don't know how to implement it to my code (how to send actual HttpResponseMessage by Application_Error) and this but again I have no clue how it should be changed.


EDIT

This is my regular error handler controller:

public ActionResult Handler(HttpException exception)
{
    Response.ContentType = "text/html";
    if (exception != null)
    {
        Response.StatusCode = exception.GetHttpCode();
        ViewBag.StatusString = (HttpStatusCode)exception.GetHttpCode();
        return View("Handler", exception);
    }
    return View("Internal");
}

And I've tried this for test purposes, and it's also not working (the client receive HttpResponseMessage with "Bad Request" as ReasonPhrase.

public HttpResponseMessage Handler(HttpException exception)
{
    Response.ContentType = "text/html";
    if (exception != null)
    {
        return new HttpResponseMessage
        {
            Content = new StringContent("[]", new UTF8Encoding(), "application/json"),
            StatusCode = HttpStatusCode.NotFound,
            ReasonPhrase = "TEST"
        };
    }
    return null;
}

Solution

  • So in my Controller that is responsible of showing the error view (which is created and triggered in Application_Error method) I've added the StatusDescription into the Response. It's not ideal and it override the actual StatusCode string, but it works.

    public class ErrorController : Controller
    {
        public ActionResult Handler(HttpException exception)
        {
            Response.ContentType = "text/html";
            if (exception != null)
            {
                Response.StatusCode = exception.GetHttpCode();
                Response.StatusDescription = exception.Message;
                ViewBag.StatusString = (HttpStatusCode)exception.GetHttpCode();
    
                return View("Handler", exception);
            }
    
            return View("Internal");
        }
    }