Scotty H
Scotty H

Reputation: 6714

Debugging exception through multiple nested async calls

Per the answer to this question, the form for capturing an exception thrown by an asynchronous method looks like this:

public async void DoFoo()
{
    try
    {
        await Foo();
    }
    catch (ProtocolException ex)
    {
          /* The exception will be caught because you've awaited the call. */
    }
}

Great. This seems to disintegrate if I want to bubble up several levels of asynchrony though. Here's where the exception originates:

internal static async Task MakePdfPagesFromPdf(Pdf pdf, byte[] pdfBytes, int jobId)
{
    IEnumerable<Image> pdfAsImages = PdfOperations.PdfToImagesPdfium(pdfBytes, dpi);

    if(pdfAsImages.Count() < 1)
    {
        throw new ArgumentException("PDF has no pages.");
    }

    // ... more code ...
}

Here's the method that calls MakePdfPagesFromPdf:

internal static async Task ProcessBase64Pdf(Pdf pdf, int jobId, string componentDesignName)
{
    byte[] pdfBytes = ConvertBase64ToPdfByteArray(pdf.Url); // Base64 data is in pdf.Url
    await UploadPdfToAwsS3(pdf, pdfBytes, jobId, componentDesignName);
    try
    {
        await MakePdfPagesFromPdf(pdf, pdfBytes, jobId);
    }
    catch(ArgumentException argumentException)
    {
        throw argumentException;
    }
}

I catch the exception like in the example cited at the beginning of this question. Debugging asserts that this catch block is hit. However, I need to bubble the exception up one more level, to inside a controller route:

try
{
    await PdfsController.ProcessBase64Pdf(pdf, componentDesign.JobId, componentDesign.Name);
}
catch (ArgumentException argumentException)
{
    // Now do stuff with the exception                  
}

It doesn't hit this highest level catch at a breakpoint. Removing the intermediate catch has no effect. The route continues and returns, but I am not able to hit breakpoints after the ArgumentException is thrown from the intermediate catch. What's going on here and how can I hit breakpoints through this whole asynchronous stack?

Upvotes: 0

Views: 571

Answers (2)

Kevin Up
Kevin Up

Reputation: 801

I'm guessing Argument exception is part of an inner exception. And is not the thrown exception. You should change catch (ArgumentException argumentException) to catch (ArgumentException exception) to call "all" exceptions.

Upvotes: -1

Itsik
Itsik

Reputation: 3930

If the method that you want to propogate the exception is async void (such as in your example of DoFoo), then the issue is that there is no Task object to propagate the exception with (since the method is void and does not return a Task)

Another thing I suggest is to not throw argumentException, but rather just throw, as the former loses the call stack of the original exception

Upvotes: 2

Related Questions