ReactiveUI's ReactiveCommand Exception handling

Viewed 778

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!

0 Answers
Related