ASP.NET Core中try...catch捕获DbUpdateException后控制台仍输出异常
问题描述
使用Minimal API开发接口时,针对数据表license_plate字段的UNIQUE唯一约束,通过try..catch捕获DbUpdateException处理重复车牌号的入库场景,实现代码如下:
app.MapPost("/vehicles", (VehiclesContext db, Vehicle vehicle) => { var entity = db.Add(vehicle); try { db.SaveChanges(); return Results.CreatedAtRoute("GetVehicle", new { inventoryNumber = entity.Entity.InventoryNumber }, entity.Entity); } catch (DbUpdateException) { var error = new JsonObject { ["error"] = $"Creating vehicle failed because such license plate already exists: {vehicle.LicensePlate}" }; return Results.BadRequest(error); } }).AddFilter<ValidationFilter<Vehicle>>();
传入重复车牌号触发异常时,接口已经正常返回400响应,但控制台仍然会输出异常信息。调整appsettings.json及appsettings.Development.json中Microsoft.AspNetCore相关的LogLevel配置,将日志级别从Warning修改为Information也无法屏蔽该日志。
原因说明
这个现象和异常是否被捕获没有关系:
- EF Core 内置了独立的日志逻辑,当数据库执行操作抛出异常时,会先将异常以错误级别写入配置的日志输出渠道,再把异常向上抛给调用方。代码里写的
catch只是接住了向上传递的异常,不会阻止EF Core内部已经完成的日志输出动作。 - 之前修改
Microsoft.AspNetCore命名空间下的日志规则不生效,是因为这条异常日志的输出类别是Microsoft.EntityFrameworkCore.Database,不属于ASP.NET Core本身的日志范畴,对应的配置规则不会匹配到这条日志。
处理方案
- 配置日志过滤规则:在日志配置中针对EF Core数据库类别的日志调高过滤阈值,跳过这类预期内的异常日志输出
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "Microsoft.EntityFrameworkCore.Database": "Error" } } }
- 增加前置校验:在执行保存操作前,先查询库中是否存在相同车牌号的记录,从源头避免异常抛出,同时保留catch块作为高并发场景下的兜底逻辑
app.MapPost("/vehicles", async (VehiclesContext db, Vehicle vehicle) => { // 前置唯一性校验 if (await db.Vehicles.AnyAsync(v => v.LicensePlate == vehicle.LicensePlate)) { var error = new JsonObject { ["error"] = $"Creating vehicle failed because such license plate already exists: {vehicle.LicensePlate}" }; return Results.BadRequest(error); } var entity = db.Add(vehicle); await db.SaveChangesAsync(); return Results.CreatedAtRoute("GetVehicle", new { inventoryNumber = entity.Entity.InventoryNumber }, entity.Entity); }).AddFilter<ValidationFilter<Vehicle>>();
提示:使用异步版本的EF Core方法(
SaveChangesAsync、AnyAsync)能获得更好的接口吞吐量,是Minimal API下的推荐写法。
内容的提问来源于stack exchange,提问作者JohnyL
相关产品推荐
相关产品推荐

