1

When an exception is thrown in one of my controllers, I'm catching it in my base class with OnException and I would like to pass the exception object to the index action of my ErrorController to display in a view.

In the example below I'm using TempData which ends up getting discarded before it reaches my ErrorController.

I know TempData only lasts until the next request but why isn't this making it that far?

I'm also open to other ways of solving this.

Test Controller

public class TestController : BaseController
{
    public ActionResult Index()
    {
        throw new Exception("test");
    }
}

Base Controller

public class BaseController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled)
            return;

        filterContext.ExceptionHandled = true;
        // Redirect to a different controller than the one that threw the exception
        filterContext.Result = RedirectToAction("Index", "Error");
        filterContext.Controller.TempData["exception"] = filterContext.Exception;
    }
}
tereško
  • 58,060
  • 25
  • 98
  • 150
user3953989
  • 1,844
  • 3
  • 25
  • 56

2 Answers2

1

You should create your own Exception Filter for treat the error

public class CustomExceptionHandlerAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if(filterContext.ExceptionHandled)
            return;

        ConfigureResponse(filterContext);

        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
        {
            {"controller", Test},
            {"action", Index},
            {"exceptionMessage", filterContext.Exception.Message}
        });

        // log your error
        base.OnException(filterContext);
    }

    private void ConfigureResponse(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 500;

        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }        
}

And then you should register your Filter, in your FilterConfigclass:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomExceptionHandlerAttribute());
    }
}

Now when your application generate an unhandled exception, this will be treated for this ActionFilter.

And your action will be:

public ActionResult Test(string exceptionMessage)
{
    return View(exceptionMessage);
}
Pedro Benevides
  • 1,970
  • 18
  • 19
  • Will this pass the entire Exception object and can it be passed to a difference controller than the one that threw the exception? – user3953989 Jan 10 '16 at 11:48
  • I've edited my answer and fixed the code. Yes, you can pass to a different controller, but why should you want to propagate the Exception object, the purpose of the Exception filter, is to treat the exception, wich means, in there you should do your logic with Exception object. – Pedro Benevides Jan 10 '16 at 13:59
  • @user3953989 any progress? – Pedro Benevides Jan 10 '16 at 22:45
  • I believe so, I think it was actually with my TempData provider. Once I get it figured out 100% I'll update here – user3953989 Jan 10 '16 at 23:03
0

you don't need to save Exception in viewData . when happen an exseption or error just redirect user to custome View like Error and show Error to user Like this : set below model for your model :

@model System.Web.Mvc.HandleErrorInfo

and now you can read what error happen and save it in db and show user a message.

below link in slimilar to your question :

Link

Community
  • 1
  • 1
Uthman Rahimi
  • 708
  • 5
  • 22