none
[C# Debugging] Correct exception-handling for async methods

    Question

  • Hey guys

    I'm a lil in trouble with debugging my project (RHR-Patcher).
    My project is basically written asynchronously. In order to make it executable in a console-app I added synchronous implementations using TaskEngine.

    Well now I have following code:

    public class Test
    {
        public Task<string> GetUsername()
        {
            return await VerifyLogin();
        }
    
        public async Task<string> VerifyLogin()
        {
            string username;
            try
            {
                /* Some awaitable Web-Requests here */
                response = await request.GetResponseAsync(); // causes an InvalidCredentialException
            }
            catch (InvalidCredentialException e)
            {
                throw new MyOwnExtension("Invalid username or password");
            }
            return username;
        }
    }
    
    internal class Program
    {
        internal static void Main(string[] args)
        {
            Test test = new Test();
            Console.WriteLine(test.GetUsername().RunSync());
        }
    }

    I want the debugger to break at Line 18 (throw new MyOwnExtension();) but it breaks at Line 29 (test.GetUsername().RunSync())

    Enabling "Common Language Runtime Exceptions" doesn't work since the debugger then breaks at Line 14 (request.GetResponseAsync()) instead of Line 18.

    How can I debug my project correctly?

    Thanks in advance

    Tuesday, April 11, 2017 1:36 PM

All replies

  • The debugger breaks into code when it runs across an unhandled exception. Exceptions actually can be triggered twice. The first time is the first chance exception and is generally only handled by the debugger. It is at this point that the runtime starts looking for a catch block to handle the exception. If no catch block handles the exception then the exception becomes a second chance exception and any attached debugger breaks into the code and puts you on the appropriate line. Basically if you continue at this point your app is going to crash.

    With a Task the exception isn't thrown until the result of the task is retrieved or you wait for the task. It is at this point the exception is triggered and the aforementioned process occurs. So given your code I would expect the behavior you're seeing.

    I'm not really sure why it is important for you to break into the code when the exception is thrown. The debugger gives you complete access to the debugging information including where it was thrown from so actually breaking at that point isn't necessary. However there are several different ways to get the behavior you want, all of them only apply while in the debugger though.

    The simplest option is to put a breakpoint on the throw statement. Then the debugger will pause before the exception is thrown.

    Second option is to enable first chance exception handling for that exception using the Exception Settings dialog in the debugger. You can tell the debugger to break when the exception is thrown, irrelevant of whether it is handled or not. This is generally an unnecessary measure and not one I generally recommend that you do.

    The debugger's exception details tells you everything you need to know. If you find it limiting then consider using a VS extension to provide more info. I personally use OzCode which has a very nice exception UI. Still VS 2017 exception dialog is pretty nice and can handle any exception your code will throw.

    Michael Taylor
    http://www.michaeltaylorp3.net

    • Proposed as answer by Ryan Software Tuesday, April 11, 2017 5:07 PM
    Tuesday, April 11, 2017 1:54 PM
    Moderator
  • Hi manuth,

    You probably using F10 - Step Over that is why you are getting on line 19. Try using F11 - Step Into, to go inside that function then Step Over with F10, see what happens.


    Thanks,
    Sabah Shariq

    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered "Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]

    Tuesday, April 11, 2017 3:25 PM
    Moderator
  • Hi manuth,

    If your issue is solved please Mark as answer or Vote as helpful post to the appropriate answer so that it will help other members to find solution if they faces similar issue.

    Your understanding and cooperation will be grateful.

    Thanks,
    Sabah Shariq

    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered "Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]

    Friday, May 12, 2017 1:04 PM
    Moderator