Caliburn-Micro / Caliburn.Micro

A small, yet powerful framework, designed for building applications across all XAML platforms. Its strong support for MV* patterns will enable you to build your solution quickly, without the need to sacrifice code quality or testability.
http://caliburnmicro.com/
MIT License
2.79k stars 775 forks source link

ConductorBaseWithActiveItem swallows exceptions in ActivateItemAsync #863

Open nkreipke opened 1 year ago

nkreipke commented 1 year ago

Exceptions thrown in ActivateItemAsync, including all other methods called from the default implementation (TryDeactivateAsync, TryActivateAsync, NotifyOfPropertyChange, OnActivationProcessed) are silently discarded.

Repro:

public class MainViewModel : Conductor<Model>.Collection.OneActive
{
    public MainViewModel()
    {
        Items.AddRange(new []
        {
            new Model(),
            new Model(),
            new Model(),
        });
    }

    public override Task ActivateItemAsync(Model item, CancellationToken cancellationToken = new CancellationToken())
    {
        throw new Exception("please notice me");
    }
}

When selecting an item in a WPF ListBox, nothing happens. This is especially bad if there is additional code after the exception, which is simply not being executed without any indication.

I've found a similar issue #745 which is probably related.

The reason is that the setter of ActiveItem calls ActivateItemAsync without awaiting the task. This is a regression from 3.x. I realize awaiting in a setter is not possible and this might be a design issue:

https://github.com/Caliburn-Micro/Caliburn.Micro/blob/145c4804a1235130190eaab089963dc9c6762c7f/src/Caliburn.Micro.Core/ConductorBaseWithActiveItem.cs#L20