Danny
Danny

Reputation: 466

SignalR stream AggregateException in server-side hub; how to catch this?

We get the following AggregateException in the following piece of code, and we don't understand how we can catch this exception. The code is in a asp.net core SignalR server application.

Any suggestion?

public async Task MetricsStream(IAsyncEnumerable<ReadPointMetrics> stream)
{
    try
    {
        await foreach (var metrics in stream) // this is line 224
        {
            try
            {
                await readerDeviceHub.StoreMetrics(readerId, metrics);
            } catch (Exception e)
            {
                // we don't end up here
                log?.Error(e, "Error in storing metrics");
            }
        }
    } catch (Exception e)
    {
        // we don't end up here
        log?.Warning(e, "Exception in metrics stream");
    }
}
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. (Stream canceled by client.)
 ---> System.Exception: Stream canceled by client.
   at System.Threading.Channels.AsyncOperation`1.GetResult(Int16 token)
   at System.Threading.Channels.ChannelReader`1.ReadAllAsync(CancellationToken cancellationToken)+MoveNext()
   at System.Threading.Channels.ChannelReader`1.ReadAllAsync(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at HarmonyBackend.Hubs.ReaderDeviceV1Hub.MetricsStream(IAsyncEnumerable`1 stream) in /builds/nedap-harmony/harmony/HarmonyBackend/Hubs/ReaderDeviceV1Hub.cs:line 224
   at HarmonyBackend.Hubs.ReaderDeviceV1Hub.MetricsStream(IAsyncEnumerable`1 stream) in /builds/nedap-harmony/harmony/HarmonyBackend/Hubs/ReaderDeviceV1Hub.cs:line 224
   --- End of inner exception stack trace ---

Upvotes: 1

Views: 170

Answers (1)

Jim
Jim

Reputation: 962

You can capture in the caller to MetricsStream function with a WaitAll. If you have linqpad, this example will simulate what you are getting.

async void Main()
{
    var tasks = new [] {
        Success(),
        Fail(),
    };
    
    try
    {
        //await Task.WhenAll(tasks);    // will get Exception("Kaboom!"
        Task.WaitAll(tasks); // will Get Agggregate Exception
    }
    catch(AggregateException ex)
    {
        Console.WriteLine("Aggregate Exception");
        // can grab the inner exceptions.
        ex.Dump();
    }
    catch(Exception ex)
    {
        ex.Dump();
    }
    
    
}

async Task Success()
{
    await Task.Delay (TimeSpan.FromSeconds(5));
    return;
}

async Task Fail()
{
    await Task.Delay (TimeSpan.FromSeconds (5));
    throw new Exception("Kaboom!");
}

Upvotes: 1

Related Questions