Web API OWIN启动异常处理
本文关键字:异常处理 启动 OWIN API Web | 更新日期: 2023-09-27 18:04:58
在我的c# Web API中,我试图添加一个全局异常处理程序。我一直在使用自定义全局ExceptionFilterAttribute
来处理异常并返回HttpResponseMessage
:
public override void OnException(HttpActionExecutedContext context)
{
...
const string message = "An unhandled exception was raised by the Web API.";
var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(message),
ReasonPhrase = message
};
context.Response = httpResponseMessage;
}
对于处理控制器级别抛出的异常来说,这已经工作得很好了。
然而,在开发过程中,由于数据库连接问题,我们的OWIN启动文件抛出了一个错误,然而,返回了一个标准的IIS异常,而不是通过全局异常处理程序,并且将完整的HTML返回给我们的API消费者。
我已经尝试了几种不同的方法来捕获在我自己的启动中抛出的异常:
Custom ApiControllerActionInvoker
:
public class CustomActionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
var result = base.InvokeActionAsync(actionContext, cancellationToken);
if (result.Exception != null && result.Exception.GetBaseException() != null)
{
...
}
return result;
}
}
自定义ExceptionHandler
:
public class CustomExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
...
base.Handle(context);
}
public override bool ShouldHandle(ExceptionHandlerContext context)
{
return true;
}
}
定制OwinMiddleware
组件:
public class CustomExceptionMiddleware : OwinMiddleware
{
public CustomExceptionMiddleware(OwinMiddleware next) : base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch (Exception ex)
{
...
}
}
}
最后使用Application_Error
:
protected void Application_Error(object sender, EventArgs e)
{
...
}
但是似乎没有什么能捕捉到异常。
有人知道捕获异常并返回HttpResponseMessage
的方法吗?或者我已经尝试过的方法是否有效?
非常感谢。
我有一个可以正确执行此操作的应用程序。在我的例子中,我编写了一个中间件类,它总是返回一条消息,告诉调用者服务不可用,因为在启动期间出现了错误。这个类在我的解决方案中被称为FailedSetupMiddleware
。它的轮廓看起来像这样:
public class FailedSetupMiddleware
{
private readonly Exception _exception;
public FailedSetupMiddleware(Exception exception)
{
_exception = exception;
}
public Task Invoke(IOwinContext context, Func<Task> next)
{
var message = ""; // construct your message here
return context.Response.WriteAsync(message);
}
}
在我的Configuration
类中,我有一个try...catch
块,在配置过程中抛出异常的情况下,仅用FailedSetupMiddleware
配置OWIN管道。
我的OWIN启动类是这样的:
[assembly: OwinStartup(typeof(Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
try
{
//
// various app.Use() statements here to configure
// OWIN middleware
//
}
catch (Exception ex)
{
app.Use(new FailedSetupMiddleware(ex).Invoke);
}
}
}