exceptiongoogle-cloud-firestoreasync-awaitgrpcaggregateexception

c# wpf How to catch FirestoreChangeListener exceptions


I am creating several FirestoreChangeListeners (following the User Guide at https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Firestore/userguide.html) and everything is working fine, but when there is a network problem, a System.AggregateException is being thrown with the inner exception being a Grpc.Core.RpcException with Status of "Transport Closed" or "Failed to connect" (This makes sense).

The problem is I can't figure out how to catch or handle these inner exceptions, which are thrown by the FirestoreChangeListeners, or how I should structure the method to do be able to do this.

I've tried adding try/catch in multiple places, tried adding ContinueWith to the listener, but regardless I still get unhandled System.AggregateException.

enter image description here

The documentation says the Listen method is a "convenience" method that supposedly helps in monitoring the Listener... and it does include a ListenerTask method that returns a Task. Perhaps I need to do something with these tasks... Everything I have read suggestions I should await this, but since it's an async listener that runs in the background for the whole time the program is running, I'm not sure what method should await... wouldn't await block the whole method?

FirestoreChangeListener Listen Method

My code is:

  public void Connect()
    {
      // Authentication code...
    
      if (authenticated) CreateFirestoreChangeListeners();
    }
    
    public void CreateFirestoreChangeListeners()
    {
      foreach (var docRef in documentReferences.Values)
      {
        FirestoreChangeListener listener = docRef.Listen(querySnapshot =>
        {
          try
          {
            ProcessSnapshot(querySnapshot);
          }
          catch (Exception ex)
          {
            Debug.WriteLine("FirestoreChangeListener: " + ex);
          }
        });
    
        listener.ListenerTask.ContinueWith((task) =>
        {
          Console.WriteLine("Task faulted");
          var ae = task.Exception;
          if (ae != null)
          {
            ae.Flatten().Handle(ex =>
            {
              Console.WriteLine("Exception Handled");
              return true;
            });
          }
        });
    
        firestoreChangeListeners.Add(listener);
      }
    }

Thanks very much for any assistance anyone can give!

Kind Regards, Damian


Solution

  • As per Jon's investigation at https://github.com/googleapis/google-cloud-dotnet/issues/5462, there is a bug in the underlying gRPC code.

    Suggested workaround by Jon is also working fine and a good solution to this problem:

    TaskScheduler.UnobservedTaskException += (sender, args) =>
    {
        if (args.Exception is AggregateException && args.Exception.InnerException is RpcException)
        {
            args.SetObserved();
        }
    };
    

    Thanks!