在我的.NET Core Web API项目中,许多控制器端点都具有类似于此示例的代码
public async Task<ActionResult<User>> UpdateUserUsernameAsync(/* DTOs */)
{
try
{
User user = null; // Update user here
return Ok(user);
}
catch (EntityNotFoundException entityNotFoundException) // map not found to 404
{
return NotFound(entityNotFoundException.Message);
}
catch (EntityAlreadyExistsException entityAlreadyExistsException) // map duplicate name to 409
{
return Conflict(entityAlreadyExistsException.Message);
}
catch (Exception exception) // map any other errors to 500
{
return new StatusCodeResult(StatusCodes.Status500InternalServerError);
}
}
我想为控制器创建一个映射,以捕获异常并将其映射到HTTP响应,然后再将其发送回客户端。
4年前曾提出过类似的问题
在NestJs中,可以通过扩展基类来定义自己的映射,例如
export class MyCustomException extends HttpException {
constructor() {
super('My custom error message', HttpStatus.FORBIDDEN);
}
}
从这里获取https://docs.nestjs.com/exception-filters#custom-exceptions
因此,基本上我想定义看起来像此示例代码的映射类(这仅显示了我的伪实现)
// Map MyCustomException to NotFound
public class MyCustomExceptionMapping<TCustomException> : IExceptionMapping<TCustomException>
{
public ActionResult Map(TCustomException exception)
{
return NotFound(exception.Message);
}
}
接下来,我可以将控制器端点方法清理为
public async Task<ActionResult<User>> UpdateUserUsernameAsync(/* DTOs */)
{
User user = null; // Update user here
return Ok(user);
}
每当引发异常时,API都会尝试查找正确的映射接口。否则,它将发送回500。
定义此类映射并避免对项目中的每个异常都进行大量切换非常好。
使用异常过滤器,它将在控制器引发异常时被调用,您可以定义自定义响应。微软文档
public class MyExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
HttpStatusCode status;
var message = "";
var exceptionType = context.Exception.GetType();
if (exceptionType is EntityNotFoundException)
{
status = HttpStatusCode.NotFound;
message = context.Exception.Message;
}
else if (exceptionType is EntityAlreadyExistsException)
{
status = HttpStatusCode.Conflict;
message = context.Exception.Message;
}
else
{
status = HttpStatusCode.InternalServerError;
message = "Internal Server Error.";
}
//You can enable logging error
context.ExceptionHandled = true;
HttpResponse response = context.HttpContext.Response;
response.StatusCode = (int)status;
response.ContentType = "application/json";
context.Result = new ObjectResult(new ApiResponse { Message = message, Data = null });
}
}
要在所有控制器上使用过滤器,必须在Startup.cs的ConfigureServices方法中注册它
services.AddMvc(config =>
{
config.Filters.Add(typeof(MyExceptionFilter));
})
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句