-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Windows] Unwrap AggregateException when catching exceptions from Task.Wait() method #602
Conversation
Hi, we are not sure what you are trying to improve here. |
In all cases Here is the issue: the caller of I changed all other |
Hi, I mean, what does this change achieve for real? How is user experience impacted and what are the motivations for this? |
My app is affected by the issues I described. I've got some crash reports when using AppCenter.Push 1.3.
|
Do you have a reproduction scenario for this crash? |
I don't have steps. It reproduces not very often according to crash count. For now I can tell that the crash occurs only while executing code from in process background task. |
But how do we know this patch solves a crash that we don't know how to reproduce? |
My crash logs say that app crashes because It will prevent the crash. Although I am not sure about the reason of underlying |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please try adding a unit test that (with mocks) that would crash if we don't have this patch.
@@ -52,7 +53,7 @@ public Storage() : this(DefaultAdapter()) | |||
internal Storage(IStorageAdapter adapter) | |||
{ | |||
_storageAdapter = adapter; | |||
_queue.Add(new Task(() => InitializeDatabaseAsync().Wait())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like @MatkovIvan mentioned in a conversation we had, just using .GetAwaiter().GetResult()
would remove the need for an extension utils, please switch to that and remove the additional extension.
Hi @guperrot |
@@ -85,7 +85,7 @@ public void GetLogsQueryError() | |||
var mockAdapter = new Mock<IStorageAdapter>(); | |||
mockAdapter.Setup( | |||
a => a.GetAsync(It.IsAny<PredType>(), It.IsAny<int>())) | |||
.Throws(new StorageException()); | |||
.ThrowsAsync(new StorageException()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ThrowsAsync()
allows to setup mock that returns faulted task. Throws()
throws right away without returning a task.
@@ -8,26 +8,11 @@ public static class TaskExtension | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, thanks for the changes. However since we use GetAwaiter().GetResult() directly in code, we should remove this utility.
Hi. I noticed strange behavior of unit tests. Running all tests complete successfully, but if I filter tests with "Storage" and run them then
Seems like 'HandleSendingSuccess' needs to await for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On develop if I run those 4 tests at once like you did, they are all green.
However on your branch it fails so this is a regression that needs to be fixed.
Waiting for a next release of moq4 where an issue affecting this PR will be resolved |
Hi @snrnats, are you still blocked on moq release? |
Hi @guperrot . Yes, still waiting for the next moq4 release. I'm trying to reach out to authors of the moq4, hope they will give us more information about the next release Update: probable there will be a release of moq4 in the next few days |
You will also need to fix the conflicts, a big refactoring was introduced to address #517. |
@@ -85,11 +85,11 @@ public void GetLogsQueryError() | |||
var mockAdapter = new Mock<IStorageAdapter>(); | |||
mockAdapter.Setup( | |||
a => a.GetAsync(It.IsAny<PredType>(), It.IsAny<int>())) | |||
.Throws(new StorageException()); | |||
.ThrowsAsync(new StorageException()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use
.Throws(TaskExtension.GetFaultedTask(new StorageException()))
to avoid moq bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line of code produce an error Error CS1503 Argument 1: cannot convert from 'System.Threading.Tasks.Task<Microsoft.AppCenter.Storage.StorageException>' to 'System.Exception'
.
Anyway Throws()
is implemented differently then ThrowsAsync()
. I think that in most cases we should use ThrowsAsync()
. Compare
/// Throws exception
private static Task Throw()
{
throw new Exception();
return Task.Delay(1000);
}
/// Return faulted task
private static async Task ThrowAsync()
{
throw new Exception();
await Task.Delay(1000);
}
I have another way to rewrite it. We could use Returns()
with a faulted task. It will look bulky but will do what was intended.
.Returns(TaskExtension.GetFaultedTask<List<Microsoft.AppCenter.Storage.Storage.LogEntry>>(new StorageException()))
I can try to change it in a such way if we don't want to wait for a moq4 release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I mean Returns
with a faulted task of course. You understood my idea correctly 👍
@@ -24,7 +24,7 @@ public void InitializeStorageTest() | |||
[TestMethod] | |||
public void CountEmptyStorage() | |||
{ | |||
var count = _storage.CountLogsAsync(StorageTestChannelName).RunNotAsync(); | |||
var count = _storage.CountLogsAsync(StorageTestChannelName).GetAwaiter().GetResult(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests can be async
and I've already replaced it partially.
async
/await
looks like right replacement instead of GetAwaiter().GetResult()
You don't necessarily change all the tests in the project, only those that relate to your fix.
I reverted changes that are not related to fix |
We need to unwrap AggregateException when using Task.Wait() method. So that the caller will get original exception.