title: Handling Web API Exceptions At MVC With Handler
body: <p>I have some questions about exception handling at MVC 4. </p>
  
  <p>I had implemented <code>HandleErrorAttribute</code> and derived a new attribute to customize. It works really good; but i don't want to redirect user a custom error page everytime. </p>
  
  <p>Some of errors that i got at Actions, throwing from Web API and i want to show them to user at current page. 
  For example if user wants to create a record but WebAPI throws an exception because of invalid modelstate, exception details shown in Create view in friendly way.</p>
  
  <p>But HandleErrorAttribute redirects Error.cshtml by default.</p>
  
  <p>I can handle every exception in Actions but i think there can be another way.</p>
  
  <p>Also i followed <a href="http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc" rel="nofollow">http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc</a> to implement <code>HandleErrorAttribute</code></p>
  
  <pre><code> public class CustomHandleErrorAttribute : HandleErrorAttribute {
          private readonly ILogger _logger;
  
          public CustomHandleErrorAttribute() {
              _logger = new NLogger(typeof(CustomHandleErrorAttribute));
          }
  
          public override void OnException(ExceptionContext filterContext) {
              if(filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) {
                  return;
              }
  
              if(new HttpException(null, filterContext.Exception).GetHttpCode() != 500) {
                  return;
              }
  
              if(!ExceptionType.IsInstanceOfType(filterContext.Exception)) {
                  return;
              }
  
              // if the request is AJAX return JSON else view.
              if(filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
                  filterContext.Result = new JsonResult {
                      JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                      Data = new {
                          error = true,
                          message = filterContext.Exception.Message
                      }
                  };
              }
              else {
                  var controllerName = (string)filterContext.RouteData.Values["controller"];
                  var actionName = (string)filterContext.RouteData.Values["action"];
                  var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                  filterContext.Result = new ViewResult {
  
                      ViewName = View,
                      MasterName = Master,
                      ViewData = new ViewDataDictionary&lt;HandleErrorInfo&gt;(model),
                      TempData = filterContext.Controller.TempData
                  };
              }
  
              _logger.Error(filterContext.Exception.Message, filterContext.Exception);
  
              filterContext.ExceptionHandled = true;
              filterContext.HttpContext.Response.Clear();
              filterContext.HttpContext.Response.StatusCode = 500;
  
              filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
          }
      }
  </code></pre>
  
  <p>I made Web API calls via HttpClient and wrapper class. For example a Get request is like below.</p>
  
  <pre><code> public async Task&lt;BrandInfo&gt; Create(BrandInfo entity) {
              using(var apiResponse = await base.PostAsync(BaseUriTemplate, entity)) {
  
                  if(apiResponse.IsSuccess) {
                      return apiResponse.Model;
                  }
  
                  throw new HttpApiRequestException(
                      string.Format(HttpRequestErrorFormat, (int)apiResponse.Response.StatusCode, apiResponse.Response.ReasonPhrase),
                      apiResponse.Response.StatusCode, apiResponse.HttpError);
              }
          }
  </code></pre>