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?