获取 blazor 错误边界中的当前异常

hes*_*lar 7 c# logging exception blazor .net-6.0

我有一个在我的应用程序的特定上下文中生成的异常。我希望能够收集它,将其发送到记录器并恢复之前的状态。 设想

问题是无法访问此错误绑定异常,因为其当前异常属性受到保护。 在此输入图像描述

解决办法是什么?

Net*_*oke 7

我遇到了同样的问题,在研究了源代码之后,很容易从 ErrorBoundary 的 ErrorContent 中获取当前的异常。

<ErrorBoundary>
                    <ChildContent>
                        @Body
                    </ChildContent>
                    <ErrorContent Context="Exception">
                        <div>
                             @Exception.Message<br/>
                        </div>
                    </ErrorContent>
                </ErrorBoundary>
Run Code Online (Sandbox Code Playgroud)

从ErrorContent的Context(RenderFragment)中获取当前异常(参见上面的代码示例)。

错误边界基础 ->

/// <summary>
    /// The content to be displayed when there is an error.
    /// </summary>
    [Parameter] public RenderFragment<Exception>? ErrorContent { get; set; }
Run Code Online (Sandbox Code Playgroud)


Aul*_*tar 5

CurrentException 属性是受保护的,而不是私有的,因此您可以定义此类:

\n
public class MyErrorBoundary : ErrorBoundary\n{\n    public new Exception? CurrentException => base.CurrentException;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后在所有代码中将 ErrorBoundary 替换为 MyErrorBoundary 。瞧\xc3\xa0。

\n

编辑:这是我如何在文件 ContainerWithExceptionHandling.razor 中使用 MyErrorBoundary 的示例:

\n
@code {\n    [Parameter(CaptureUnmatchedValues = true)]\n    public Dictionary<string, object> Attributes { get; set; }\n\n    [Parameter]\n    public RenderFragment ChildContent { get; set; }\n\n    private MyErrorBoundary boundary;\n}\n\n<div @attributes="Attributes">\n    <ExceptionBoundary @ref="boundary">\n        <ChildContent>\n            @ChildContent\n        </ChildContent>\n        <ErrorContent>\n            <ExceptionView Exception="@boundary.CurrentException"\n                HowToResume="(() => boundary.Recover())" />\n        </ErrorContent>\n    </ExceptionBoundary>\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n

在此示例中,ExceptionView 是一个自定义组件,它在带有“恢复”按钮的框中显示异常消息。

\n

我的 MainLayout.razor 有:

\n
<ContainerWithExceptionHandling class="content px-4">\n    @Body\n</ContainerWithExceptionHandling>\n
Run Code Online (Sandbox Code Playgroud)\n

这样,如果网页的某个组件在渲染时抛出错误消息,那么页面的主要部分将被易于阅读的错误消息替换,并且恢复正常操作将相对容易。

\n


Ara*_*ani 1

我希望能够收集它,将其发送到记录器并恢复之前的状态。

创建一个组件如下(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();       
}
Run Code Online (Sandbox Code Playgroud)

}

Error组件可以使用 Blazor 内置记录器记录错误,并通过该方法使用ToastrProcessError显示 JavaScript 错误消息。显然,其他记录器如 Serilog、Elmah 甚至其他自定义记录器都可以使用此方法进行登录。

StateHasChanged当错误处理方法想要直接干预发生异常的组件的用户界面的渲染时将使用。例如,当我们想要在发生错误后更改页面的渲染元素(更改按钮的颜色或标签或文本框的字体颜色或......)。

现在,我们App.razor按如下方式编辑组件:

<Error>
    <Router ...>
        ...
    </Router>
</Error>
Run Code Online (Sandbox Code Playgroud)

事实上,我们通过自己的自定义组件(Error.razor)将 Router 组件封装起来,以便将 Error 组件级联到任何将 Error 视为 的程序组件[CascadingParameter]

现在,在其他组件中按如下方式处理错误就足够了:

@code {
    [CascadingParameter]
    public Error? Error { get; set; }

    private void CreatePost()
    {
        try
        {
           throw new InvalidOperationException("a message!");
        }
        catch (Exception ex)
        {
            Error?.ProcessError(ex);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,Error 组件被定义为一个CascadingParametertry catch 块,并且在 try catch 块中,ProcessError调用 Error 组件的方法并将发出的异常发送给它。在我的示例中,Error 组件只有一种错误处理方法。显然,该组件可以有几种其他自定义错误处理方法用于不同的目的。

要将日志保存在服务器上的文本文件中,可以使用 Serilog,其方法在此处进行说明。您还可以使用自定义日志提供程序将日志保存到数据库。