Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Hello.
In MudBlazor we recently did this change: https://github.com/MudBlazor/MudBlazor/pull/8203/files#diff-7258903903d30bdc973979ca0d64c61adbee3f4441e47749100907f522060a47
We added AsNonRenderingEventHandler
(that was copied from official MS document) to our internal onclick
and now the ErrorBoundary
doesn't catch the exceptions that are fired within the AsNonRenderingEventHandler
event:
<ErrorBoundary>
<ChildContent>
<MudButton OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
<MudText>Click me</MudText>
</MudButton>
</ChildContent>
<ErrorContent Context="exc">
<MudAlert Severity="Severity.Error">Exception: @exc.Message</MudAlert>
</ErrorContent>
</ErrorBoundary>
@code {
async Task ProcessSomething()
{
throw new ApplicationException("TESTING");
}
}
You will see in console:
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: TESTING
System.ApplicationException: TESTING
at Try.UserComponents.__Main.ProcessSomething()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at MudBlazor.MudBaseButton.OnClickHandler(MouseEventArgs ev)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
rather than the ErrorContent
.
The weird thing about it if that I use alternative to AsNonRenderingEventHandler
:
public abstract class MudBaseButton : MudComponentBase, IHandleEvent
{
Task IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, object? arg) => callback.InvokeAsync(arg);
}
Then everything will work as expected and ErrorBoundary
is working
another weird thing is that if I change this:
public static Func<TValue, Task> AsNonRenderingEventHandler<TValue>(Func<TValue, Task> callback) => new AsyncReceiver<TValue>(callback).Invoke;
to this:
public static Func<TValue, Task> AsNonRenderingEventHandler<TValue>(Func<TValue, Task> callback)
{
var receiver = new AsyncReceiver<TValue>(callback);
return async value => await receiver.Invoke(value);
}
Then the ErrorBoundary
will catch the exception as well, but the problem is that this return async value => await receiver.Invoke(value);
and this return new AsyncReceiver<TValue>(callback).Invoke
should be EQUIVALENT in C# (except that for first one an asyncstatemachine is created, but end result should be the same and no side effects).
upd: well, with this snippet https://try.mudblazor.com/snippet/cOQSERlIheRAyAJe I just found out that async value => await receiver.Invoke(value)
doesn't prevents re-rendering, but the IHandleEvent
implementation in component works, so this doesn't explain few moments:
- Why with the original
EventUtil
from docs theErrorBoundary
doesn't work. - Why with my offered version the exception flows, but the re-render is not prevented.
- Why if I implement
IHandleEvent
in the component it works great - the exception flows and no re-render is happening, but theEventUtil
in 1. or 2. doesn't work as I expect?
I described the same in this in MudBlazor issue: MudBlazor/MudBlazor#8365 (comment)
@SteveSandersonMS could you please explain, as I'm very confused on what's going on.
Expected Behavior
ErrorBoundary
to work with AsNonRenderingEventHandler
Steps To Reproduce
This would require to fork the https://github.com/MudBlazor/MudBlazor repository and play with the MudButton.razor and MudButtonBase and the snippet from https://try.mudblazor.com/snippet/caQSaxvSoRhvMaSP (added very minimal repro below, so not relevant anymore)
upd: Minimal reproduction without MudBlazor:
BlazorEventUtilsIssue.zip
Exceptions (if any)
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: TESTING
System.ApplicationException: TESTING
at Try.UserComponents.__Main.ProcessSomething()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at MudBlazor.MudBaseButton.OnClickHandler(MouseEventArgs ev)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
.NET Version
8.0.103
Anything else?
No response