Logging 如何处理内部web api错误?

Logging 如何处理内部web api错误?,logging,error-handling,asp.net-web-api,Logging,Error Handling,Asp.net Web Api,在我们的应用程序中,我们有一组相当简单的日志挂钩(MVC和API控制器上的IEExceptionFilters和应用程序中的一个额外的catch all_Error()),但有一整类错误不会触发任何错误。如果从WebAPI本身内部或从内部使用的东西(如依赖项解析程序创建的类的类型初始值设定项)引发异常,我得到的只是发送到客户端的500响应 我发现捕获错误详细信息的唯一方法是使用HttpConfiguration.IncludeErrorDetailPolicy来配置应用程序以发出错误详细信息——

在我们的应用程序中,我们有一组相当简单的日志挂钩(MVC和API控制器上的IEExceptionFilters和应用程序中的一个额外的catch all_Error()),但有一整类错误不会触发任何错误。如果从WebAPI本身内部或从内部使用的东西(如依赖项解析程序创建的类的类型初始值设定项)引发异常,我得到的只是发送到客户端的500响应

我发现捕获错误详细信息的唯一方法是使用HttpConfiguration.IncludeErrorDetailPolicy来配置应用程序以发出错误详细信息——但是,向世界广播错误详细信息是一种明显的错误做法,因此我更愿意将其完全关闭,或者将其设置为有条件的(例如,仅本地)..但这意味着要远程访问应用程序运行的服务器,并使用能够检查响应(如IE或Google Chrome)的工具在本地调用API,以了解发生了什么

我在这里看到了另一个类似的问题(),但我们认为提出的解决方案(使用DelegatingHandler检查响应)不符合我们的需要。是否真的没有可以钩住的事件、可以使用的扩展点或类似的东西来捕获实际发生的异常

(顺便说一句,我想我可以将IncludeErrorDetailPolicy更改为Always,并使用另一个线程中提供的解决方案捕获MessageHandler中的错误详细信息,记录它们,然后手动从发送给客户端的响应中删除它们,但这将是一个令人讨厌的黑客行为。)


想法/

好吧,我明白你想做什么。谢谢你的澄清。WebAPI有一个模型,其中错误响应不一定是由异常引起的。例如,任何人都可以返回带有400的HttpResponseMessage,而不会实际引发异常。在许多情况下,内置框架错误以相同的方式工作,不会引发异常

现在,我觉得你的建议听起来不错。您可以将ErrorDetailPolicy设置为Always,并实现一个记录错误的消息处理程序,并使用仅包含该消息的不同HttpError。下面是它可能的样子:

公共类ErrorHandlingMessageHandler:DelegatingHandler
{
受保护的异步覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
HttpResponseMessage response=await base.SendAsync(请求,取消令牌);
HttpError错误;
if(response.TryGetContentValue(输出错误))
{
日志错误(错误)
//使用不会泄漏内部信息的HttpError
(response.Content作为ObjectContent.Value=newhttperror(error.Message);
}
返回响应;
}
}
请注意,我们没有清除现有的错误。我们正在创建一个新的,以减少泄漏信息的风险。信息应始终安全地发送回。这不包括发回模型状态,但如果需要,您可以随时将其复制到新错误


考虑这一点的一种方法是,您可以记录本应发送给本地客户机的响应,然后仍然向远程客户机发送一条不包含错误详细信息的安全消息。

好的,我明白您的意图。谢谢你的澄清。WebAPI有一个模型,其中错误响应不一定是由异常引起的。例如,任何人都可以返回带有400的HttpResponseMessage,而不会实际引发异常。在许多情况下,内置框架错误以相同的方式工作,不会引发异常

现在,我觉得你的建议听起来不错。您可以将ErrorDetailPolicy设置为Always,并实现一个记录错误的消息处理程序,并使用仅包含该消息的不同HttpError。下面是它可能的样子:

公共类ErrorHandlingMessageHandler:DelegatingHandler
{
受保护的异步覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
HttpResponseMessage response=await base.SendAsync(请求,取消令牌);
HttpError错误;
if(response.TryGetContentValue(输出错误))
{
日志错误(错误)
//使用不会泄漏内部信息的HttpError
(response.Content作为ObjectContent.Value=newhttperror(error.Message);
}
返回响应;
}
}
请注意,我们没有清除现有的错误。我们正在创建一个新的,以减少泄漏信息的风险。信息应始终安全地发送回。这不包括发回模型状态,但如果需要,您可以随时将其复制到新错误


考虑这一点的一种方法是,您可以记录您本应发送给本地客户端的响应,然后仍然向远程客户端发送一条不包含错误详细信息的安全消息。

我们向Microsoft Partner Network打开了一个支持请求,他们返回了我认为更好的答案

其想法是将平台的默认IHttpControllerActivator实现替换为将默认控制器创建行为包装为任何其他所需行为的实现

在我们的例子中,这意味着用try/catch/throw构造和对日志服务的调用包装DefaultHttpControllerActivator的Create方法。这可能不会提供100%的覆盖率,但我们缺少的大多数例外都涉及控制器的创建,因此它应该会有很大帮助


我真的很想能够在HttpControllerDispatcher中钩住HandleException方法,但它是私有的和静态的,所以我想。

我们向Microsoft合作伙伴网络提出了一个支持请求,他们回来后给出了我认为更好的答案