异常没有冒泡到错误处理中间件?

Exceptions not bubbling up to Error Handling Middleware?(异常没有冒泡到错误处理中间件?)
本文介绍了异常没有冒泡到错误处理中间件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个中间件,它应该捕获我的异常并将http响应代码正确设置为异常发生,但似乎无论我做什么,我仍然得到OK响应。

这是中间件

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;

    /// <inheritdoc />
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    /// <summary>
    /// Called by execution pipeline
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        var code = HttpStatusCode.InternalServerError; // 500 if unexpected

        var result = JsonConvert.SerializeObject(new { error = ex.Message });
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;
        return context.Response.WriteAsync(result);
    }
}

它是这样添加到我的启动程序中的:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMiddleware(typeof(ErrorHandlingMiddleware));
    if (env.IsDevelopment())
    {
        //app.UseDeveloperExceptionPage();
    }else
    {
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles(new StaticFileOptions
    {
        ServeUnknownFileTypes = true
    });
    app.UseDefaultFiles();
    app.UseCookiePolicy();
    app.UseMvc();

    app.UseCors("CorsPolicy");

    app.UseMvcWithDefaultRoute();

    app.UseSwaggerAndUI(Configuration)
       .UseCustomHealthCheck();
}

抛出错误的代码为:

public Task<string> SaveFileAsync(string path, byte[] file, string fileType, CancellationToken cancellationToken = default)
{
    var filename = _filenameProvider.GetFilename(path, fileType);
    var fullPath = _fileSystem.Path.Combine(path, filename).Replace('/', '\');

    try
    {
        _fileSystem.Directory.CreateDirectory(fullPath);
        // Error in the FileSystem abstraction library: https://github.com/System-IO-Abstractions/System.IO.Abstractions/issues/491
        //await _fileSystem.File.WriteAllBytesAsync(fullPath, file, cancellationToken);

        _fileSystem.File.WriteAllBytes(fullPath, file);

        return Task.FromResult(filename);
    }
    catch (Exception ex)
    {
        Log.Error(ex.Message, nameof(SaveFileAsync), _userId);

        throw;
    }
}

,控制器为:

public class PatientDocumentController : BaseController
{
    private readonly IPatientFilePusher _patientFilePusher;


    /// <inheritdoc />
    public PatientDocumentController(IPatientFilePusher filePusher)
    {
        _patientFilePusher = filePusher;
    }

    /// <summary>
    /// Pushes a patient file to the emr
    /// </summary>
    /// <param name="request">Contains the file data.</param>
    /// <param name="token">A auto-generated token that allows for halting execution.</param>
    /// <returns>Ok when complete.</returns>
    [HttpPost]
    public async Task<IActionResult> PushPatientDemographicsAsync([FromBody] FilePushRequest request, CancellationToken token)
    {
        await _patientFilePusher.PushFileAsync(request, token);

        return Ok();
    }
}

返回的响应正文包含异常,但http状态代码保持为200。我的中间件上的catch分支从未被调用。

推荐答案

您有一个函数,该函数具有异步签名,但不遵循异步处理方式:

public Task<string> SaveFileAsync(string path, byte[] file, string fileType, CancellationToken cancellationToken = default)

当函数返回Task/Task<T>时,它引发的任何异常都应该被捕获并放置在返回的任务上。async关键字将为您完成此操作。

因此,您应该将该函数更改为async

public async Task<string> SaveFileAsync(string path, byte[] file, string fileType, CancellationToken cancellationToken = default)
{
    var filename = _filenameProvider.GetFilename(path, fileType);
    var fullPath = _fileSystem.Path.Combine(path, filename).Replace('/', '\');

    try
    {
        _fileSystem.Directory.CreateDirectory(fullPath);
        // Error in the FileSystem abstraction library: https://github.com/System-IO-Abstractions/System.IO.Abstractions/issues/491
        //await _fileSystem.File.WriteAllBytesAsync(fullPath, file, cancellationToken);

        _fileSystem.File.WriteAllBytes(fullPath, file);

        return filename;
    }
    catch (Exception ex)
    {
        Log.Error(ex.Message, nameof(SaveFileAsync), _userId);

        throw;
    }
}

或将异常放在返回的任务上:

public Task<string> SaveFileAsync(string path, byte[] file, string fileType, CancellationToken cancellationToken = default)
{
    try
    {
        var filename = _filenameProvider.GetFilename(path, fileType);
        var fullPath = _fileSystem.Path.Combine(path, filename).Replace('/', '\');

        _fileSystem.Directory.CreateDirectory(fullPath);
        // Error in the FileSystem abstraction library: https://github.com/System-IO-Abstractions/System.IO.Abstractions/issues/491
        //await _fileSystem.File.WriteAllBytesAsync(fullPath, file, cancellationToken);

        _fileSystem.File.WriteAllBytes(fullPath, file);

        return Task.FromResult(filename);
    }
    catch (Exception ex)
    {
        Log.Error(ex.Message, nameof(SaveFileAsync), _userId);

        return Task.FromException<string>(ex);
    }
}

这篇关于异常没有冒泡到错误处理中间件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)