Exception RequestStartup中的异常

Exception RequestStartup中的异常,exception,nancy,Exception,Nancy,我正在使用Nancy创建一个web api。我有一个已签名的令牌,它是从用户传递来进行身份验证的。在我自己的引导程序中的RequestStartup方法中没有此身份验证。现在,在某些情况下,例如,当我不能很好地处理签名令牌时,我希望能够抛出一个异常,并由Nancy的OnError hanhdler处理。但是,在查找RequestStartup之前引发的异常未被捕获。该请求生成一个500错误,我想返回一些带有我自己错误信息的其他内容 我有一个明显的例子,我抛出一个异常,但也有可能在GetIdent

我正在使用Nancy创建一个web api。我有一个已签名的令牌,它是从用户传递来进行身份验证的。在我自己的引导程序中的RequestStartup方法中没有此身份验证。现在,在某些情况下,例如,当我不能很好地处理签名令牌时,我希望能够抛出一个异常,并由Nancy的OnError hanhdler处理。但是,在查找RequestStartup之前引发的异常未被捕获。该请求生成一个500错误,我想返回一些带有我自己错误信息的其他内容

我有一个明显的例子,我抛出一个异常,但也有可能在GetIdentity()方法中抛出一个异常

我正在寻找任何关于如何处理这个问题的意见

    protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
    {
        base.RequestStartup(container, pipelines, context);

        pipelines.OnError.AddItemToStartOfPipeline((ctx, exception) =>
                container.Resolve<IErrorHandler>().HandleException(ctx, exception));

        var identity = container.Resolve<IAuthenticationController>().GetIdentity();
        var configuration = new StatelessAuthenticationConfiguration(_ => identity);
        StatelessAuthentication.Enable(pipelines, configuration);

        var logManager = new LogManager(context);
        pipelines.AfterRequest.AddItemToEndOfPipeline(_ => logManager.Log());

        try
        {
            X509Certificate2 clientCert = context.Request.ClientCertificate as X509Certificate2;
            container.Resolve<ICertificateValidator>().Validate(clientCert);
        }
        catch (Exception ex)
        {
            throw new MklServerAuthenticationException(ErrorCodes.WrongOrNonexistingCertificate, ex);
        }
    }
protectedoverride void RequestStartup(TinyIoCContainer容器、IPipelines管道、NancyContext上下文)
{
base.RequestStartup(容器、管道、上下文);
pipelines.OneError.AddItemToStartOfPipeline((ctx,异常)=>
container.Resolve().HandleException(ctx,exception));
var identity=container.Resolve().GetIdentity();
var配置=新的无状态身份验证配置(=>identity);
无状态身份验证。启用(管道、配置);
var logManager=新的logManager(上下文);
pipelines.AfterRequest.AddItemToEndOfPipeline(=>logManager.Log());
尝试
{
X509Certificate2 clientCert=context.Request.ClientCertificate作为X509Certificate2;
container.Resolve().Validate(clientCert);
}
捕获(例外情况除外)
{
抛出新的MklServerAuthenticationException(ErrorCodes.ErrorOrnonExistingCertificate,ex);
}
}

找到了解决上述问题的方法,并认为其他人可能想知道。将上面代码中包含GetIdentity()调用的行替换为以下内容:

        Identity identity = null;
        try
        {
            identity = container.Resolve<IAuthenticationController>().GetIdentity(requestInfo);
        }
        catch (Exception ex)
        {
            var exception = new MklAuthentcationException(ErrorCodes.TokenInvalid, ex);
            context.Response = container.Resolve<IErrorHandler>().HandleException(context, exception);
            pipelines.BeforeRequest.Invoke(context, CancellationToken.None);
        }
Identity=null;
尝试
{
identity=container.Resolve().GetIdentity(requestInfo);
}
捕获(例外情况除外)
{
var exception=new MklAuthentcationException(ErrorCodes.TokenInvalid,ex);
context.Response=container.Resolve().HandleException(上下文,异常);
pipelines.BeforeRequest.Invoke(上下文,CancellationToken.None);
}
我使用了nancy中陈述的事实:

在处理请求之前调用PreRequest钩子。如果钩子返回一个非空响应,那么处理将中止,并返回提供的响应

因此,通过在PreRequest钩子上设置一个响应(在本例中是我的错误)并调用它,返回我的错误并停止执行


也许不是最好的解决办法。。。如果您能想出更好的方法,请告诉我。

或者更确切地说,上面的方法实现了BeforeRequest挂钩,并在那里完成您的工作。