我有一块中间件,应该可以捕获我的异常并在发生异常时正确设置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
分支。
答案 0 :(得分:0)
您有一个具有异步签名但不遵循异步处理方式的函数:
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);
}
}