title: Asp.NET MVC action filter custom exception handling
body: <p>Context:</p>
  
  <p>We have a Asp.NET MVC client that interacts with IBM's P8 Content Engine.  End users are authenticated via network through AD.  However, sometimes the user identity passed to us does not always match what we have, thus we cannot retrieve the user's information and our MVC app cannot interact with AD.  I have an action filter that does this user information lookup and sometimes the lookup result is null.  I like to return my Error view and pass it a HandleErrorInfo model.  I tried throwing an exception but somehow HandleError and even Application_Error block somehow doesn't seem to do anything. </p>
  
  <p>Here's my registered custom UserLookupAttribute filter:</p>
  
  <pre><code>public class UserLookupAttribute : ActionFilterAttribute, IActionFilter
      {
  
          public override void OnActionExecuting(ActionExecutingContext filterContext)
          {
              HttpContextBase context = filterContext.HttpContext;
              UserInfo userInfo = null;
              if (context.User.Identity.IsAuthenticated)
              {
                  if (context.Session != null &amp;&amp; context.Session["UserInfo"] != null) { userInfo = (UserInfo)context.Session["UserInfo"]; }
                  string networkId = (string.IsNullOrEmpty(SecurityConstants.UserImpersonateId)) ? GetNetworkId(context.User.Identity.Name) : GetNetworkId(SecurityConstants.UserImpersonateId);
                  if (userInfo == null &amp;&amp; !string.IsNullOrEmpty(networkId))
                  {
                      userInfo = GetUserInfoCache(networkId);
                      if (userInfo != null)
                          context.Session["UserInfo"] = userInfo;
                  }
  
                  if (userInfo != null)
                  {
                      context.Items["UserInfo"] = userInfo;
                      filterContext.Controller.ViewBag.User = userInfo;                    
                  }
                  //else
                  //    throw new HttpException((int)HttpStatusCode.Unauthorized, "You login credential is not recognized by FileNet.");
              }
              base.OnActionExecuting(filterContext);
          }
  }
  </code></pre>
  
  <p>Application_Error code:</p>
  
  <pre><code>protected void Application_Error()
          {
              var httpContext = HttpContext.Current;
  
              var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
              var currentController = " ";
              var currentAction = " ";
  
              if (currentRouteData != null)
              {
                  if (currentRouteData.Values["controller"] != null &amp;&amp; !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
                  {
                      currentController = currentRouteData.Values["controller"].ToString();
                  }
  
                  if (currentRouteData.Values["action"] != null &amp;&amp; !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
                  {
                      currentAction = currentRouteData.Values["action"].ToString();
                  }
              }
  
              var ex = Server.GetLastError();
  
              var controller = new ErrorController();
              var routeData = new RouteData();
              var action = "Index";
  
              if (ex is HttpException)
              {
                  var httpEx = ex as HttpException;
  
                  switch (httpEx.GetHttpCode())
                  {
                      case 404:
                          action = "NotFound";
                          break;
  
                      // others if any
  
                      default:
                          action = "Index";
                          break;
                  }
              }
  
              httpContext.ClearError();
              httpContext.Response.Clear();
              httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
              httpContext.Response.TrySkipIisCustomErrors = true;
              routeData.Values["controller"] = "Error";
              routeData.Values["action"] = action;
  
              controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
              ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
          }
  </code></pre>