[英]How to correctly bubble up exceptions from Tasks
我正在尝试编写一个异步方法,该方法从数据库中读取一个项目并在读取前后提供一定数量的验证。 快乐之路没问题,但我无法弄清楚如何正确抛出异常。
这是我的代码:
protected override async Task<Entity> InternalRead<TEntity>(object id)
{
var result = this.context.Set<Entity>().FindAsync(id);
return await result;
}
public Task<TEntity> Read<Entity>(object id) where TEntity : class
{
return InternalRead<Entity>(id)
.ContinueWith(entityTask =>
{
var entity = entityTask.Result;
if (entity != null && !entity.IsHidden)
throw new UnauthorizedAccessException();
return entity;
});
}
[Fact]
public async Task InvalidIdThrowsExpectedException()
{
var db = *getDBCode*
var identity = new Identity();
await Assert.ThrowsAsync<UnauthorizedAccessException>(() => accessor.Read<TradingStyle>(1, identity));
}
id 为1
的实体是隐藏的,当我单步执行代码时,我可以看到按预期抛出了异常,但测试看到抛出了AggregateException
而不是UnauthorizedAccessException
。 我看不出我的设置和我一直在阅读的示例之间有什么不同,但我很困惑为什么 Assert.ThrowAsync 没有展开内部异常。
不要使用ContinueWith
; 改用await
。 对于大多数异步代码来说,这是一个很好的通用规则。 ContinueWith
是一种低级方法,具有令人惊讶的默认行为; await
以您期望的方式工作:
public async Task<TEntity> Read<Entity>(object id) where TEntity : class
{
var entity = await InternalRead<Entity>(id);
if (entity != null && !entity.IsHidden)
throw new UnauthorizedAccessException();
return entity;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.