在我们的应用程序中,我们有一组相当简单的日志钩子( MVC和API控制器上的IExceptionFilters和Application_Error()中的一个额外的通用钩子),但是有一大类错误不会触发它们中的任何一个。如果一个异常是从WebAPI内部抛出的,或者是从内部使用的东西(比如依赖项解析器创建的类的类型初始化器)抛出的,那么我得到的只是一个发送给客户端的500响应。
我发现捕获错误详细信息的唯一方法是使用HttpConfiguration.IncludeErrorDetailPolicy配置应用程序来发出错误详细信息--然而,向全世界广播错误详细信息是众所周知的糟糕做法,所以我更喜欢完全关闭它,或者将其设置为有条件的(例如,仅本地)。..But意味着远程连接到应用程序正在运行的服务器,并使用可以检查响应的工具(如IE或Google Chrome)在本地调用API,以找出发生了什么。
我在这里看到了另一个类似的问题(here),但提出的解决方案(使用DelegatingHandler检查响应)不能满足我们的需求。真的没有我可以钩住的事件,我可以使用的扩展点,或者类似的东西来捕获实际发生的异常吗?
(顺便说一句,我想我可以将我的IncludeErrorDetailPolicy更改为Always,并使用另一个线程中提供的解决方案来捕获MessageHandler中的错误详细信息,记录它们,然后手动将它们从发送到客户机的响应中删除,但这将是一个糟糕的技巧。)
想法?:/
发布于 2013-02-26 23:57:05
我们向Microsoft合作伙伴网络提出了支持请求,他们返回了我认为更好的答案。
其思想是将平台的默认IHttpControllerActivator实现替换为包装了默认控制器创建行为和任何其他所需行为的实现。
在我们的示例中,这意味着将DefaultHttpControllerActivator的Create方法包装为try/catch/throw构造和对日志记录服务的调用。这可能不会给出100%的覆盖率,但我们遗漏的大多数异常都涉及到控制器的创建,所以它应该会有很大帮助。
我真的很希望能够在HttpControllerDispatcher中挂接HandleException方法,但它既是私有的,又是静态的,所以呢。
发布于 2013-01-19 04:25:42
好的,我知道你想做什么。谢谢你的澄清。WebAPI有一个模型,在这个模型中,错误响应不一定是由异常引起的。例如,任何人都可以返回一个带有400的HttpResponseMessage,而实际上不会抛出异常。在许多情况下,内置的框架错误以相同的方式工作,而不会抛出异常。
现在,我认为你的建议对我来说很好。您可以将ErrorDetailPolicy设置为Always,并实现一个记录错误的消息处理程序,并使用仅包含该消息的不同HttpError。下面是它可能的样子:
public class ErrorHandlingMessageHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
HttpError error;
if (response.TryGetContentValue(out error))
{
LogError(error)
// Use an HttpError that doesn't leak internal information
(response.Content as ObjectContent).Value = new HttpError(error.Message);
}
return response;
}
}请注意,我们并没有清除现有的错误。我们正在创建一个新的,以减少信息泄露的风险。消息应该始终是安全的,可以发送回去。这不包括发送回模型状态,但如果需要,您可以随时将其复制到新的错误中。
考虑这一点的一种方法是,您可以记录本应发送给本地客户端的响应,然后仍然向远程客户端发送不包含错误详细信息的安全消息。
https://stackoverflow.com/questions/14405102
复制相似问题