CommunityToolkit / dotnet

.NET Community Toolkit is a collection of helpers and APIs that work for all .NET developers and are agnostic of any specific UI platform. The toolkit is maintained and published by Microsoft, and part of the .NET Foundation.
https://docs.microsoft.com/dotnet/communitytoolkit/?WT.mc_id=dotnet-0000-bramin
Other
2.99k stars 294 forks source link

OnPropertyChanged cannot rise the exception #781

Closed ali50m closed 11 months ago

ali50m commented 11 months ago

Describe the bug

I tried to raise exception in the partial OnPropertyChanged method, but the exception cannot be caught in "Start without debugging" mode. This issue during I report a similar issue to fody/PropertyChanged(https://github.com/Fody/PropertyChanged/issues/993). However, I found this issue also happen to "CommunityToolkit.Mvvm".

Regression

No response

Steps to reproduce

repo: https://github.com/ali50m/FodyOnChangedMethodIssue/tree/toolkit

VM Code:

internal partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    private int _input;

    [ObservableProperty]
    private string _output = "0";

    partial void OnInputChanged(int value)
    {
        if (Random.Shared.Next(10) > 5)
        {
            throw new InvalidOperationException();
        }
        Output = $"{value}";
    }
}

View code:

    <Window.DataContext>
        <fodyOnChangedMethodIssue:MainViewModel />
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding Input, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="{Binding Output}" />
    </StackPanel>

Expected behavior

Exception can be thrown or caught. Or it is a potential weakness for the application.

Screenshots

screenshots

IDE and version

VS 2022 Preview

IDE version

No response

Nuget packages

Nuget package version(s)

CommunityToolkit.Mvvm v8.2.2

Additional context

No response

Help us help you

No, just wanted to report this

JochenMader commented 11 months ago

Hi there

As mentioned in your Fody issue the Exception is eaten by the Binding. So this seems to me as expected behavior. The Exception can be handled with the DispatcherUnhandledException Event. See also here: Handling exceptions in WPF

best regards

ali50m commented 11 months ago

@JochenMader Thank you for your reply! I add the following code to App.xaml.cs for catching the exceptions. But still no lucky to catch the exception.

public partial class App
{
    public App()
    {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        DispatcherUnhandledException += App_DispatcherUnhandledException;
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show(e.ExceptionObject.ToString());
    }

    private void App_DispatcherUnhandledException(
        object sender,
        DispatcherUnhandledExceptionEventArgs e
    )
    {
        MessageBox.Show(e.Exception.ToString());
    }
}
JochenMader commented 11 months ago

@ali50m I told you something wrong. With the DispatcherUnhandledException event you can catch unhandled exceptions in the application. But exceptions, that occur in the wpf binding, are allready handled. But there is also a solution for this. I found this one: How can I turn binding errors into runtime exceptions?

ali50m commented 11 months ago

@JochenMader Many thanks for your investigation and help! As the post on stackoverflow, I find the nuget WpfBindingErrors can help to catch and rethrow the exception now. Thanks!