代码之家  ›  专栏  ›  技术社区  ›  gvdm

如何捕获db约束冲突并抛出userfriendlyexception?

  •  0
  • gvdm  · 技术社区  · 6 年前

    我有一个 CrudAppService 定义如下:

    public class MyAppService : AsyncCrudAppService<MyEntity, MyDto, int, PagedAndSortedResultRequestDto, MyCreateDto, MyDto>, IMyAppService, ITransientDependency
    {
        private readonly IRepository<MyEntity> _MyRepository;
    
        public MyAppService(IRepository<MyEntity> repository) : base(repository)
        {
            _MyRepository = repository;
        }
    }
    

    我还定义了实体字段的唯一约束 MyEntity 因此,当我尝试创建多个具有相同字段值的实体时,它会中断并抛出 DbUpdateException 是的。很好。

    现在我想抓住这个异常并重新抛出 UserFriendlyException 为用户显示消息。我试着在 Create() 方法,但它不会被捕获。

    public override Task<MyDto> Create(MyCreateDto input)
    {
        try
        {
            return base.Create(input);
        }
        catch(Exception ex)
        {
            // Never gets here
            throw new UserFriendlyException("A message for the user");
        }
    }
    

    所以,我试着实施 IEventHandler<AbpHandledExceptionData> 过滤 DbUpdateException异常 然后扔掉 用户友好异常 以下内容:

    class MyExceptionHandler : IEventHandler<AbpHandledExceptionData>, ITransientDependency
    {
        public MyExceptionHandler()
        {
        }
    
        public void HandleEvent(AbpHandledExceptionData eventData)
        {
            if (eventData.Exception is DbUpdateException dbUpdateEx) {
                throw new UserFriendlyException("A message for the user");
            }
        }
    }
    

    调试,我可以看到它到达 throw new UserFriendlyException 行,但什么也没有发生(没有向用户显示消息),因此 引发新的用户友好异常 行被隐藏/忽略。

    我能做些什么来解决这个问题?

    谢谢您。

    2 回复  |  直到 6 年前
        1
  •  2
  •   aaron    6 年前

    我试着在 Create() 方法,但它不会被捕获。

    你需要打电话 _unitOfWorkManager.Current.SaveChanges() 以下内容:

    public override Task<MyDto> Create(MyCreateDto input)
    {
        try
        {
            var dto = base.Create(input);
            _unitOfWorkManager.Current.SaveChanges();
            return dto;
        }
        catch (DbUpdateException ex)
        {
            throw new UserFriendlyException("A message for the user");
        }
    }
    

    或者,覆盖 SaveChanges SaveChangesAsync 在dbcontext中:

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbUpdateException ex)
        {
            throw new UserFriendlyException("A message for the user");
        }
    }
    
    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        try
        {
            return await base.SaveChanges();
        }
        catch (DbUpdateException ex)
        {
            throw new UserFriendlyException("A message for the user");
        }
    }
    
        2
  •  0
  •   seb49    6 年前

    您正在使用ASP.NET Core吗?

    因为在abp文档中:( https://aspnetboilerplate.com/Pages/Documents/Handling-Exceptions ) 本文档适用于ASP.NET MVC和Web API。如果您对asp.net core感兴趣,请参阅asp.net core文档。

    我必须使用tempdata和viewbag在模式下向用户显示错误…