2

I am having problems with unhandled exceptions being thrown in the task awaiter. These exceptions are just ignored and never propagated anywhere.

Code example:

Task<bool> Execute()
{
    TaskCompletionSource<bool> tcsrc = new TaskCompletionSource<bool>();
    Task.Delay(50).ContinueWith((t) => {
        tcsrc.SetResult(true);
    });
    return tcsrc.Task;
}

async Task<bool> Test()
{
    bool result = await Execute();
    throw new Exception("test");
    return result;
}

In this example, Test() awaits on task returned by Execute() and then throws an exception. This exception is never handled anywhere and the only place I am able to catch it is Application's FirstChanceException handler. After this handler is executed, the exception gets just ignored.

The Test() itself is called via chain of async calls from some UI event handler. So I assume it should be propagated to that UI event handler and thrown there. But it never happens.

Is there something I miss?

Edit: According to FirstChanceException handler, the exception is reproduced three times before becoming ignored with the following stack trace:

at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
mephisto123
  • 1,400
  • 13
  • 38
  • Your code is invalid to start with - you can't declare an `async` method to return `bool`. When you change it to `Task`, it will return a task which will become faulted when you throw the exception. – Jon Skeet May 13 '14 at 09:54
  • Sorry, fixed that error. Yes, I assume the task will become faulted and the awaiter of it will receive the exception. And this exception will in its turn make parent task faulted. And so on, until the exception reaches initial UI event handler which is awaiting for it. But it never happens. – mephisto123 May 13 '14 at 09:55
  • Shouldn't `Execute` return something? – Joachim Isaksson May 13 '14 at 09:57
  • Possibly a duplicate: [TAP global exception handler](http://stackoverflow.com/q/22369179/1768303). – noseratio May 13 '14 at 13:26
  • No, my question was not about global exception handling in any way. – mephisto123 May 14 '14 at 14:25
  • @mephisto123, it's about `Task` exception propagation behavior which I answered there in details: http://stackoverflow.com/a/22395161/1768303 – noseratio May 14 '14 at 22:22
  • My question was basically about exceptions not in async task but rather in its awaiter. However, that was my mistake and the exception was not fired by another reason not related to async/await calls. – mephisto123 May 16 '14 at 05:09

1 Answers1

4

The Task<bool> returned from your Test method will become faulted. If you await that task (or call Wait() on it) then the exception will be rethrown at that point. If you choose to ignore the faulted state of the task, then yes, you'll be ignoring the exception.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I am awaiting task returned from Test() method in another async method. And awaiting result of that async method in another async method. The chain ends in some UI event handler method as I wrote in the post. – mephisto123 May 13 '14 at 09:59
  • @mephisto123 You did write that, but I don't think that's correct. (If it's correct, then you can catch the exception without any problems.) Most likely, you're forgetting to await *somewhere*, but that *somewhere* is not part of your question. My first guess would be that your event handler is not async, and that you're calling an async method from it and discarding the returned task, but without seeing the relevant code, a guess is as good a response as you're going to be able to get. –  May 13 '14 at 10:03
  • @mephisto123: Well you say that it's *called*, but you didn't write that you were *awaiting* the task. Without seeing your actual code, it's hard to tell what you've done wrong. Bear in mind that if you've got an `async void` method, that doesn't have anywhere clean to report its exception... you end up with it basically being reported to the synchronization context, which is unfortunately ugly. (It all gets a bit magical at that point...) – Jon Skeet May 13 '14 at 10:06
  • You were right. There is a place in the chain where I basically do the following: TaskEx.Run(async () => { .... await Foo(); .... }); And this Foo() is calling Test() somewhere below in the async call chain. Could you please advise how to properly handle exceptions in this case? – mephisto123 May 13 '14 at 10:10
  • @mephisto123: Well it sounds like you just need to await that task. But it's all pretty unclear, to be honest - you should update your question to be a *lot* clearer... or quite possibly delete (or accept) this question and ask a new one. Your original question isn't about "how do I handle exceptions from a task started with TaskEx.Run" which is what it sounds like you're *really* interested in... – Jon Skeet May 13 '14 at 10:12
  • Yes, you're right. I'll mark your answer as correct (since it is really correct) and ask a new one if I won't find existing answer. – mephisto123 May 13 '14 at 10:15