I have an exception that has been generated in a certain context of my application. I would like to be able to collect it, send it to the logger and recover the previous state.
The problem is that this error-bound exception cannot be accessed since its current exception property is protected.
What would be the solution?
CodePudding user response:
I would like to be able to collect it send it to the logger and recover the previous state.
Create a component as below (Error.razor):
@using Microsoft.Extensions.Logging
@inject ILogger<Error> Logger
@inject IJSRuntime jsRuntime
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
public void ProcessError(Exception ex)
{
Logger.LogError("Error:ProcessError - Type: {Type} Message: {Message}",
ex.GetType(), ex.Message);
jsRuntime.ToastrError("An Error has occured!");
//StateHasChanged();
}
}
Error
component can log errors using the Blazor built-in logger and display JavaScript error messages with Toastr through the ProcessError
method. Obviously, other loggers such as Serilog, Elmah and even other custom loggers can be used to log in this method.
StateHasChanged
will be used when the error handling method wants to directly intervene in the rendering of the user interface of the component where an exception occurred. For example, when we want to make a change in the rendered elements of the page after an error (change the color of a button or the font color of a label or text box or...).
Now, we edit the App.razor
component as follows:
<Error>
<Router ...>
...
</Router>
</Error>
In fact, we enclose the Router component by our own custom component (Error.razor) so that the Error component is cascaded to any program component that considers Error as [CascadingParameter]
.
Now, it is enough to process errors as follows in other components:
@code {
[CascadingParameter]
public Error? Error { get; set; }
private void CreatePost()
{
try
{
throw new InvalidOperationException("a message!");
}
catch (Exception ex)
{
Error?.ProcessError(ex);
}
}
}
As you can see, the Error component is defined as a CascadingParameter
and in a try catch block, the ProcessError
method of the Error component is called and the issued exception is sent to it. In my example, the Error component has only one error handling method. Obviously, this component can have several other custom error handling methods for different purposes.
To save the logs in a text file on the servers, you can use Serilog, the method of which is explained here. You can also save the logs to a Database with a custom log provider.