You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Task中正确抛出异常?Assert.ThrowsAsync未捕获预期异常

问题原因与解决方案

问题出在你使用ContinueWith处理异步任务的方式上:

  • ContinueWith属于传统TPL(任务并行库)API,它不会像async/await那样自动解包任务的内部异常。当你在ContinueWith的委托中访问entityTask.Result时,无论上游任务抛出异常,还是你主动抛出UnauthorizedAccessException,最终都会被封装在ContinueWith返回任务的AggregateException内部。
  • Assert.ThrowsAsync只会捕获直接抛出的目标异常,不会自动解包AggregateException的内部异常。

修正后的代码

把Read方法改为使用async/await语法,它会自动处理异常解包:

public async Task<TEntity> Read<TEntity>(object id) where TEntity : class
{
    var entity = await InternalRead<TEntity>(id);
    if (entity != null && !entity.IsHidden)
        throw new UnauthorizedAccessException();
    return entity;
}

同时修正InternalRead的泛型参数混用问题:

protected override async Task<TEntity> InternalRead<TEntity>(object id)
{
    var result = await context.Set<TEntity>().FindAsync(id);
    return result;
}

测试代码修正

确保测试方法调用的参数与方法定义一致(原代码中Read调用传了两个参数,但方法定义仅接收id,需对齐):

[Fact]
public async Task InvalidIdThrowsExpectedException()
{
    var db = /* 你的数据库实例代码 */;
    await Assert.ThrowsAsync<UnauthorizedAccessException>(() => accessor.Read<TradingStyle>(1));
}

修改后,Assert.ThrowsAsync就能正确捕获到你抛出的UnauthorizedAccessException,不会再出现AggregateException包装的问题。

内容的提问来源于stack exchange,提问作者Andy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:25:37