1

I am trying to catch exceptions within a Task I have created but they never "bubble up" to where the Task is ran from, they are always caught by Visual Studio as runtime errors.

Here is a SSCCE I have created to show the issue

using System;
using System.Threading.Tasks;

namespace ConsoleApplicationSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            CreateTheIssue();
            Console.ReadLine();
        }

        public static async void CreateTheIssue()
        {
            try
            {
                int val = await ExceptionThrowerClass.DoSomething();
            }
            catch(Exception ex)
            {
                Console.Out.WriteLine("Exception of type " + ex.GetType() + " caught, message: " + ex.Message);
            }
        }
    }

    public static class ExceptionThrowerClass
    {
        public static Task<int> DoSomething()
        {
            return Task.Run(() =>
            {
                throw new FooException("How exceptional!");
                return 1;
            });
        }
    }

    public class FooException : Exception
    {
        public FooException() : base () { }
        public FooException(String message) : base(message) { }
        public FooException(String message, Exception inner) : base (message, inner) { }
    }
}

Visual Studio notifies me when I throw FooExcepion in DoSomething that the exception is not being caught. From this SO answer and this MSDN page I thought that the exceptions would just "bubble up" to myTask.Wait() and subsequently be caught. Though this does not seem to be that case.

The project settings for this SCCEE are targeting .NET 4.5.2 and I am using Visual Studio 2015. Is it that my targeted .NET framework cannot catch exceptions in this manner? How can I catch FooException in the try/catch block within Main?

EDIT: I have altered the SSCCE to use the async/await pattern instead of Task.Wait.

Community
  • 1
  • 1
KDecker
  • 6,928
  • 8
  • 40
  • 81
  • 1
    Possible duplicate of [What is the best way to catch exception in Task?](http://stackoverflow.com/questions/12980712/what-is-the-best-way-to-catch-exception-in-task) – Dana Cartwright Sep 16 '16 at 18:28
  • 1
    Your edit has drastically changed the question. Now you have a task that is never awaited in Main. If you await the call to your async method, then it will catch the exception in Main. Async needs to bubble up with regards to which methods are async or not. – Travis J Sep 16 '16 at 18:42
  • 1
    Chameleon questions are generally considered to be rude. – Travis J Sep 16 '16 at 18:43
  • What is your exception settings in visual studio? do you catch on all thrown exceptions or on uncaught exceptions? – Scott Chamberlain Sep 16 '16 at 18:45
  • @TravisJ I apologize, I admittedly do not understand the actual difference between the first and second SSCCE, only the use of `Wait` versus `async`/`await`. I really did not try to be rude. – KDecker Sep 16 '16 at 18:46
  • @ScottChamberlain if means anything to say they are set to the default, they they are set to the default, I have never changed them. // In the Exceptions Settings window there are very many listed that would not fit in a comment. // So in all I am not exactly sure how to answer that. – KDecker Sep 16 '16 at 18:50

1 Answers1

2

Hit the Continue button, you will see that the exception does get caught in the outer try/catch. Because the exception crossed in to the innards of Task the exception was considered "User Unhanded", however Task handels it for you by putting the task in to the Faulted state. This will a exception to be re-raised when you await or .Wait() the task.

Using your original method before your edit would need to do

    try
    {
        myTask.Wait();
    }
    catch(AggregateException ex)
    {
        var innerException = ex.InnerException;
        Console.Out.WriteLine("Exception of type " + innerException .GetType() + " caught, message: " + innerException.Message);
    }

Because the Task will wrap the exceptions up in to a AggregateException, when you use await it unwraps the exception for you.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • Yes, this is what is happening. So the issue is that Visual Studio "does not understand" that the exception will be caught later, or it is that Visual Studio could potentially "catch" every exception before the code itself does but by the Exception Settings most of these are simply glanced over? – KDecker Sep 16 '16 at 18:53
  • It is that the exception could "handled" later. The debugger in visual studio is more agressive and only checks for things that are handled in the call stack of the thread that caused the exception and are in User Code. Your try/catch is in a seperate call stack and the try/catch that `Task` is using internally is in Framework code instead of User Code, that is why the debugger considers it "unhanded" – Scott Chamberlain Sep 16 '16 at 18:55
  • 1
    @KDecker If you uncheck "Just My Code" [in the debugger settings](http://i.stack.imgur.com/MhHMH.png) it will now consider the try/catch inside of `Task`'s code and the debugger will no-longer stop when the exception is thrown because there is now a try/catch in the callstack of that thread now catches the exception which it is allowed to check for. – Scott Chamberlain Sep 16 '16 at 18:57
  • Does that have any other side effects? Or is it specifically for this problem? – KDecker Sep 16 '16 at 18:58
  • I find it makes debugging slower some times if library code uses exceptions internally a lot, the only thing I ran in to in the .NET framework with that problem was classes in the `System.DirectoryServices` namespaces because it uses Exceptions for it's timeout flow controll internally. – Scott Chamberlain Sep 16 '16 at 19:00
  • No it is simply going beyond your code to check the exception in dependant libraries and code too – Mrinal Kamboj Sep 16 '16 at 19:00