Web API 过滤器未捕获从方法组抛出的异常
Web API filters not catching exceptions thrown from a method group
我正在使用 WebApi
。我的基本控制器上有一个自定义 ActionFilter
,全局添加了一个自定义 ExceptionFilter
。两者都是从 System.Web.Http.Filters
命名空间中关联的 FilterAttributes 继承的,而不是 mvc 版本。
我的一项服务中的私有方法抛出了一个异常,当它在 Linq 语句中使用时,resharper 将此方法称为方法组(在本例中为 select
).
public IEnumerable<Foo> GetFoos()
{
IEnumerable<Bar> bars = _work.BarRepository.GetAll();
//throw new Exception("I'm visible to the filters");
IEnumerable<Foo> foos = bars.Select(MakeFooFromBar);
return foos;
}
private Foo MakeFooFromBar(Bar bar)
{
// an exception is being thrown here
// which is not being caught by the filers
throw new Exception("I am invisible to the filters");
}
此异常未被任一过滤器捕获(请参阅下面的过滤器)。我的操作过滤器说没有异常,我的异常过滤器从未被命中。如果我在 Linq select(我已经注释掉的那个)之前抛出一个异常,那么这个异常就会按预期被捕获。
使用fiddler,我得到的结果是:
{
"message":"An error has occurred.",
"exceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
"exceptionType":"System.InvalidOperationException",
"stackTrace":null,
"innerException":{
"message":"An error has occurred.",
"exceptionMessage":"I am invisible to the filters",
"exceptionType":"System.Exception",
"stackTrace":""
}
}
我的动作过滤器的一部分:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
Exception exception = actionExecutedContext.Exception;
if (exception == null)
{
// do things
}
else
{
// do some other things
}
}
和我的异常过滤器的一部分:
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
// return early on certain kinds of exceptions...
_loggedErrorService.Log(actionExecutedContext.Exception);
}
You can customize how Web API handles exceptions by writing an exception filter. An exception filter is executed when a controller method throws any unhandled exception[...]
问题是,如果您从您的 WebAPI 方法 return 一个 IEnumerable<T>
,则在序列化期间,当迭代 IEnumerable<T>
时,会发生错误。这是 Select
(以及大多数其他查询运算符)的标准行为,它仅在迭代时调用传递给它的方法(在本例中为 MakeFooFromBar
),因此当您调用 Select
但很久以后。
您可以添加一个 .ToList
以导致异常在您的方法中发生。
我正在使用 WebApi
。我的基本控制器上有一个自定义 ActionFilter
,全局添加了一个自定义 ExceptionFilter
。两者都是从 System.Web.Http.Filters
命名空间中关联的 FilterAttributes 继承的,而不是 mvc 版本。
我的一项服务中的私有方法抛出了一个异常,当它在 Linq 语句中使用时,resharper 将此方法称为方法组(在本例中为 select
).
public IEnumerable<Foo> GetFoos()
{
IEnumerable<Bar> bars = _work.BarRepository.GetAll();
//throw new Exception("I'm visible to the filters");
IEnumerable<Foo> foos = bars.Select(MakeFooFromBar);
return foos;
}
private Foo MakeFooFromBar(Bar bar)
{
// an exception is being thrown here
// which is not being caught by the filers
throw new Exception("I am invisible to the filters");
}
此异常未被任一过滤器捕获(请参阅下面的过滤器)。我的操作过滤器说没有异常,我的异常过滤器从未被命中。如果我在 Linq select(我已经注释掉的那个)之前抛出一个异常,那么这个异常就会按预期被捕获。
使用fiddler,我得到的结果是:
{
"message":"An error has occurred.",
"exceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
"exceptionType":"System.InvalidOperationException",
"stackTrace":null,
"innerException":{
"message":"An error has occurred.",
"exceptionMessage":"I am invisible to the filters",
"exceptionType":"System.Exception",
"stackTrace":""
}
}
我的动作过滤器的一部分:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
Exception exception = actionExecutedContext.Exception;
if (exception == null)
{
// do things
}
else
{
// do some other things
}
}
和我的异常过滤器的一部分:
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
// return early on certain kinds of exceptions...
_loggedErrorService.Log(actionExecutedContext.Exception);
}
You can customize how Web API handles exceptions by writing an exception filter. An exception filter is executed when a controller method throws any unhandled exception[...]
问题是,如果您从您的 WebAPI 方法 return 一个 IEnumerable<T>
,则在序列化期间,当迭代 IEnumerable<T>
时,会发生错误。这是 Select
(以及大多数其他查询运算符)的标准行为,它仅在迭代时调用传递给它的方法(在本例中为 MakeFooFromBar
),因此当您调用 Select
但很久以后。
您可以添加一个 .ToList
以导致异常在您的方法中发生。