1

Closed

Exceptions from authorization filters are not caught by exception filters

description

An exception thrown from IAuthorizationFilter.ExecuteFilterAsync does not get caught by exception filters. (Exceptions thrown from awaiting the task do get caught.)

This behavior is not by design and is different from both Web API action filters and MVC authorization filters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Filters;

namespace MvcApplication2.Controllers
{
[CustomExceptions]
[CustomAuthorization]
[CustomActionFilter]
public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        // This exception is caught by the exception handler.
        throw new ApplicationException();
    }

    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }

    // POST api/values
    public void Post([FromBody]string value)
    {
    }

    // PUT api/values/5
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/values/5
    public void Delete(int id)
    {
    }

    private class CustomExceptionsAttribute : Attribute, IExceptionFilter
    {
        public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, System.Threading.CancellationToken cancellationToken)
        {
            actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            return Task.FromResult<object>(null);
        }

        public bool AllowMultiple
        {
            get { return false; }
        }
    }

    private class CustomAuthorizationAttribute : Attribute, IAuthorizationFilter
    {
        public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            // This exception is caught by the exception handler.
            throw new InvalidOperationException();
            // Compare:
            // return Task<HttpResponseMessage>.Factory.StartNew((() => { throw new InvalidOperationException(); }));
            // That exception would be caught by the exception handler.
        }

        public bool AllowMultiple
        {
            get { return false; }
        }
    }

    private class CustomActionFilterAttribute : Attribute, IActionFilter
    {
        public Task<HttpResponseMessage> ExecuteActionFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            // This exception is caught by the exception handler.
            throw new InvalidOperationException();
        }

        public bool AllowMultiple
        {
            get { return false; }
        }
    }
}
}
Closed Jun 10, 2013 at 10:37 PM by hongyes
Verified

comments

davidmatson wrote Mar 28, 2013 at 8:24 PM

I believe this bug was fixed with commit a8e957f5b5f8.