Skip to content

Commit f340828

Browse files
committed
Fix error handling in Create()
1 parent 0125fe0 commit f340828

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

async-enumerable-dotnet-test/CreateTest.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Xunit;
66
using async_enumerable_dotnet;
77
using System.Threading.Tasks;
8+
using System;
89

910
namespace async_enumerable_dotnet_test
1011
{
@@ -43,5 +44,43 @@ public async void Range_Loop()
4344
await Range();
4445
}
4546
}
47+
48+
[Fact]
49+
public async void Items_And_Error()
50+
{
51+
var result = AsyncEnumerable.Create<int>(async e =>
52+
{
53+
await e.Next(1);
54+
55+
await e.Next(2);
56+
57+
throw new InvalidOperationException();
58+
});
59+
60+
await result.AssertFailure(typeof(InvalidOperationException), 1, 2);
61+
}
62+
63+
[Fact]
64+
public async ValueTask Take()
65+
{
66+
await AsyncEnumerable.Create<int>(async e =>
67+
{
68+
for (var i = 0; i < 10 && !e.DisposeAsyncRequested; i++)
69+
{
70+
await e.Next(i);
71+
}
72+
})
73+
.Take(5)
74+
.AssertResult(0, 1, 2, 3, 4);
75+
}
76+
77+
[Fact]
78+
public async void Take_Loop()
79+
{
80+
for (int j = 0; j < 1000; j++)
81+
{
82+
await Take();
83+
}
84+
}
4685
}
4786
}

async-enumerable-dotnet/impl/CreateEmitter.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ private sealed class CreateEmitterEnumerator : IAsyncEnumerator<T>, IAsyncEmitte
3232
public bool DisposeAsyncRequested => _disposeRequested;
3333

3434
private bool _hasValue;
35+
private Exception _error;
3536

3637
public T Current { get; private set; }
3738

@@ -41,8 +42,7 @@ private sealed class CreateEmitterEnumerator : IAsyncEnumerator<T>, IAsyncEmitte
4142

4243
internal void SetTask(Task task)
4344
{
44-
_task = task;
45-
task.ContinueWith(async t =>
45+
_task = task.ContinueWith(async t =>
4646
{
4747
if (_disposeRequested)
4848
{
@@ -55,6 +55,8 @@ internal void SetTask(Task task)
5555
return;
5656
}
5757

58+
_error = ExceptionHelper.Extract(t.Exception);
59+
5860
ResumeHelper.Resume(ref _valueReady);
5961
});
6062
}
@@ -78,6 +80,13 @@ public async ValueTask<bool> MoveNextAsync()
7880
return true;
7981
}
8082
Current = default;
83+
84+
var ex = _error;
85+
if (ex != null)
86+
{
87+
_error = null;
88+
throw ex;
89+
}
8190
return false;
8291
}
8392

0 commit comments

Comments
 (0)