Finally is not being called
Rurouni opened this issue · 0 comments
I have run into interesting bug when noticed that finally is not being called.
I have an coroutine based test that uses grpc with magic onion bits and essentially it boils down to:
var joinPromise = firstClientChat.JoinRoom(new JoinChatRoom() {RoomName = "room", UserName = user1})
.ToYieldInstruction(throwOnError: true);
yield return joinPromise;
Result result = joinPromise.Result;
- when
throwOnError: true
- finally is not being called - when
throwOnError: false
- finally is being called despite same error is being thrown just one line below
I have a hunch that is something to do with how UnitTestRunner is handling chained coroutines.
To get more context inside firstClientChat.JoinRoom
there is call into SendRequestAsync
that calls into grpc stream
public IObservable<Message> SendRequestAsync(Message request)
{
//non relevant code
var replyReceivedFuture = new AsyncSubject<Message>();
var pendingOperation = new PendingOperation(requestId, replyReceivedFuture, request);
PendingOperationsByRequestId.Add(requestId, pendingOperation);
return Send(request).ContinueWith(u =>
{
return replyReceivedFuture
.Timeout(_sendTimeout)
.ObserveOnMainThread()
.Do(m => PendingOperationsByRequestId.Remove(requestId),
m => PendingOperationsByRequestId.Remove(requestId));
});
}
public IObservable<Unit> Send(byte[] data)
{
return _asyncDuplexStreamingCall.RequestStream.WriteAsync(data)
.DoOnError(e =>
{
Log.Warning(e, "{channel}: Send failed with error:{error}", this, e.Message);
});
}
what happens Is that the error is propagated from _asyncDuplexStreamingCall.RequestStream.WriteAsync(data)
then it's being intercepted in UnitTestRunner.UnwrapEnumerator
and that stops iterating all enumerators in that recursive call but because it doesn't dispose enumerator that means finally section doesn't have a chance to be called...