How to trap exceptions on GetAsync call

I am at a loss on how to trap exceptions with a GetAsync call.

If I initialize the JsonServiceClient _service variable with an invalid baseURI to test an inaccessible server and run this function, the code never hits return resp.Products, it is never trapped in the Catch. The same code structure with the .Get<> function traps the error in the Catch block.

I am sure it is something simple that I am unaware of however I have been digging through google results for hours and cant figure out what how to handle the exceptions.

    public async Task<List<ProductsModel>> GetAllProducts()
    {
        try
        {
            var resp = await _service.GetAsync<ProductsResponse>("Products/" + App.pdClientGUID);
            return resp.Products;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

Thanks
M

If you’re awaiting the task you can catch an Exception with a normal catch block, but you shouldn’t return null in a method that returns a task, either rethrow another Exception or return an empty Task result.

Yes I agree, however the code I have shared never hits either return statement if I put in an inaccessible server URI into the ServiceClient, its irrelevant what goes into the return statements it neither one is hit.

I have broken down an entire class that reproduces the problem:
public class RestService
{
private JsonServiceClient _service;

    public RestService()
    {
        _service = new JsonServiceClient("https://blahblahblah/");
    }
    public async Task<int> GetAllProductsAsync()
    {
        try
        {
            var resp = await _service.GetAsync<int>("Products/");
            return 100;
        }
        catch (Exception ex)
        {
            return -100;
        }
    }
}

In the above code neither return statement is ever hit, it might be that I am not quite using ServiceStack correctly but I have read a ton and worked through some of the samples to get to this point.

Any idea what I am doing wrong or what is happening?

Thanks
M

No idea why you can’t trap, I’ve added a test asserting that trying to access the same non-existent host can be trapped in both JsonServiceClient and newer JsonHttpClient.

Not sure why it doesn’t work for you, maybe it’s an unobserved task exception for some reason which you can try catching in your Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    TaskScheduler.UnobservedTaskException +=
        (object sender, UnobservedTaskExceptionEventArgs excArgs) => {
        excArgs.SetObserved();
    };
}

Actually I spoke too soon, on the GetAsync method there is no change, I initially ran it on the synchronous method and it worked but it always worked there.

On GetAsync it still stalls and never hits any of the Catch blocks.

I’m not able to reproduce the issue, the test above works as expected. Can you reproduce this in an isolated stand-alone program? Maybe you have something messing with ASP.NET Synchronization Context.

Definitely, its the first thing I did before I put together the thread.

https://www.dropbox.com/s/w4pprev7vpdt8uh/AsyncTest.zip?dl=0

It’s the way you’re calling it, you need to avoid calling async/await in void methods, it will work if you decorate your method with async, e.g:

    private async void Form1_Load(object sender, EventArgs e)
    {
        try
        {
            var result = await DataService.GetAllProductsAsync();
            MessageBox.Show(result.ToString());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

Damn, I knew it would be something stupid i was doing. Thanks for your patience Mythz, as always, exceptional support to match the product.

Thank you for your assistance.
M

In case anyone else runs across this thread, the other option to make it work properly is to use .ConfigureAwait()

After mythz pointed out my misunderstanding about calling async events everything I had read previously fell into place and I understand why I have read so many times that any server calls should have .ConfigureAwait() on them.

The following line also makes the exceptions trigger properly:
var result = await DataService.GetAllProductsAsync().ConfigureAwait(false);

Hopefully someone else finds this thread useful at some point.

Thanks again Mythz.

1 Like