Blazorise
Blazorise copied to clipboard
[Bug]: Exception logged for tooltip module
Blazorise Version
1.3.3
What Blazorise provider are you running on?
Material
Link to minimal reproduction, or a simple code snippet
From time to time an exception pops up in our application logs around the tooltip module. Probably the exception handling of loading stopped etc should be added
Steps to reproduce
What is expected?
What is actually happening?
Microsoft.JSInterop.JSException: Failed to fetch dynamically imported module: https://xxx/_content/Blazorise.Material/tooltip.js?v=1.3.3.0 TypeError: Failed to fetch dynamically imported module: https://xxx/_content/Blazorise.Material/tooltip.js?v=1.3.3.0 at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args) at Blazorise.Modules.BaseJSModule.InvokeSafeVoidAsync(String identifier, Object[] args) at Blazorise.Tooltip.<OnInitialized>b__11_0() at Blazorise.BaseAfterRenderComponent.OnAfterRenderAsync(Boolean firstRender) at Blazorise.BaseComponent.OnAfterRenderAsync(Boolean firstRender) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
What browsers are you seeing the problem on?
No response
Any additional comments?
No response
@David-Moreira Do you think it might be worth catching a JSException along with other exception types?
Failed to fetch dynamically imported module
When Microsoft.JSInterop.JSException + Failed to fetch dynamically imported module
I don't know if there are actual JSException that we should let propagate, so better just handle specifically, in my opinion.
Or upon further inspection of the stack trace, the method is named InvokeSafeVoidAsync. I don't remember how we use it, but it would imply, that it's completly safe and would catch anything actually?
We catch other exceptions:
protected async ValueTask InvokeSafeVoidAsync( string identifier, params object[] args )
{
try
{
var module = await Module;
if ( AsyncDisposed )
{
return;
}
await module.InvokeVoidAsync( identifier, args );
}
catch ( Exception exc ) when ( exc is JSDisconnectedException or ObjectDisposedException or TaskCanceledException )
{
}
}
Should we catch all is my point? Otherwise, is it ever truly safe?
Do our js InvokeSafeVoidAsync calls ever need to propagate any exception to the end user?
Do our js
InvokeSafeVoidAsynccalls ever need to propagate any exception to the end user?
That's a valid question. IMO, if we propagate it down to the user, then what is the point of catching exceptions?
That's right. But I think in general in Blazorise we take the approach of no exceptions.
I.e, let's say a user missconfigured a component, we don't throw an Exception telling him Parameter X is missing or the configuration is invalid.
So here, I'd probably take the same approach as it's internal code that does not need user interaction, modules are imbued/self contained in the library so there's no user setup with these? Only thing that can sometimes happen is users firewalls blocking resources, but that should still be somewhat evident when things don't work at all and the resources are blocked on the network tab?
I agree. Since we are usually quiet about the internal error, we should do the same here. But to make sure this is fixed properly we should first reproduce the error on our side. From my testing, it is really hard to reproduce it.
Only thing that can sometimes happen is users firewalls blocking resources, but that should still be somewhat evident when things don't work at all and the resources are blocked on the network tab?
Yes, the 404 should show on the browser console for any non-found or blocked resources.
Maybe you could use a ILogger in the catch clause of InvokeSafeVoidAsync and log the exception with a warning level or lower so users of Blazorise can still turn on logging to see if somehting is going wrong?
That might be a good alternative.