Как отловить исключение из ReactiveCommand?

Я знаю, как обрабатывать исключения, генерируемые асинхронными задачами, вызываемыми ReactiveCommand<T> но как мне обработать исключение, которое выдается перед возвратом задачи?

В следующем примере ThrowAndHandle Команда выдаст исключение из асинхронной задачи при выполнении, и исключение будет обработано. Команда ThrowButFailToHandle демонстрирует, что не могу использовать ThrownExceptions обработать исключение, которое возникает не внутри задачи, а перед созданием задачи. Как можно обработать такое исключение?

public class ViewModel
{
    public IReactiveCommand ThrowAndHandle { get; private set; }
    public IReactiveCommand ThrowButFailToHandle { get; private set; }

    public ViewModel()
    {
        ThrowAndHandle = ReactiveCommand.CreateAsyncTask(_ => ThrowFromTask());
        ThrowAndHandle.ThrownExceptions.Subscribe(HandleException);

        ThrowButFailToHandle = ReactiveCommand.CreateAsyncTask(_ => ThrowBeforeTaskIsReturned());
        ThrowButFailToHandle.ThrownExceptions.Subscribe(ThisMethodWillNotBeCalled);
    }

    private Task ThrowFromTask()
    {
        return Task.Run(() => 
        {
            throw new Exception("This exception will appear in IReactiveCommand.ThrownExceptions");
        });
    }

    private Task ThrowBeforeTaskIsReturned()
    {
        throw new Exception("How can I handle this exception?");
    }

    private void HandleException(Exception ex)
    {
        // This method is called when ThrownFromTask() is called
    }

    private void ThisMethodWillNotBeCalled(Exception ex)
    {   
    }
}

1 ответ

Решение

Предполагая, что ваши команды напрямую связаны с пользовательским интерфейсом, краткий ответ: вы не можете.

Исключение будет распространено на обработчик onError ExecuteAsync наблюдаемый, который игнорируется согласно реализации Execute:

    public void Execute(object parameter)
    {
        ExecuteAsync(parameter).Catch(Observable.Empty<T>()).Subscribe();
    }

Теперь, если вам необходимо поймать это исключение, вы можете:

  • обернуть ReactiveCommand в ICommand с другим Execute поведение при ошибке
  • обернуть лямбда передается CreateAsyncCommand возвратить результат задачи сбоя при исключении
  • выпуск /PR на реактивном уровне для распространения этих исключений также на ThrownExceptions
Другие вопросы по тегам