3

I'm trying to handle Exception thrown inside ReactiveUI (7.4.0.0)'s commands, but everything seems to be swllowed somehwere inside and never comes out but in Visual Studio's Output window. My test code is this:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var ata = ReactiveCommand.CreateFromTask(async () => await AsyncTaskThrowException());
            ata.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async with await:\t{ex.Message}"));
            ata.Execute();
            // Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
            // Exception thrown: 'System.Exception' in Test.exe
            // Exception thrown: 'System.Exception' in mscorlib.dll

            var atna = ReactiveCommand.CreateFromTask(() => AsyncTaskThrowException(),null, RxApp.MainThreadScheduler);
            atna.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async without await:\t{ex.Message}"));
            atna.Execute();
            // Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
            // Exception thrown: 'System.Exception' in Test.exe

            var ta = ReactiveCommand.CreateFromTask(async () => await TaskThrowException());
            ta.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async without await:\t{ex.Message}"));
            ta.Execute();
            // Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
            // Exception thrown: 'System.Exception' in Test.exe

            var tna = ReactiveCommand.CreateFromTask(() => TaskThrowException());
            tna.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async without await:\t{ex.Message}"));
            tna.Execute();
            // Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
            // Exception thrown: 'System.Exception' in Test.exe
            // Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll

            var sf = ReactiveCommand.Create(() => ThrowException());
            sf.ThrownExceptions.Subscribe(ex => Console.WriteLine($"sync:\t{ex.Message}"));
            sf.Execute();
            // Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"{nameof(ex.Message)}: {ex.Message}");
            Debug.WriteLine($"{nameof(ex.StackTrace)}: {ex.StackTrace}");
        }

        Console.ReadLine();
    }

    static async Task<string> AsyncTaskThrowException()
    {
        await Task.Delay(100);
        throw new Exception("Exception in async Task");
    }

    static Task<string> TaskThrowException()
    {
        throw new Exception("Exception in non-async Task");
    }

    static string ThrowException()
    {
        throw new Exception("Exception in sync func");
    }
}

Under each call there are the Exception's thrown if I comment everything but that .Execute() call (intentional one included). The only call that prints something is the third:

ReactiveCommand.CreateFromTask(() => TaskThrowException());

But still throws something.

Can you help me understand why the other Exceptions don't get piped into ThrownExceptions, and how to completely handle errors so they don't get logged in the Output window?

Thanks!

Sergio
  • 2,078
  • 3
  • 24
  • 41
  • 2
    `Execute()` returns an `Observable`. To make it work correctly you should subscribe to it. It's a bit poorly named, but no better name was found when naming it. – Jon G Stødle Jul 30 '17 at 21:34

0 Answers0