简体   繁体   English

在 Asp.Net Core 3.1 中处理 SignalR 集线器中的所有异常

[英]Handle all exceptions in SignalR hubs in Asp.Net Core 3.1

In Web API all the exceptions can be cought by Middleware.在 Web API 中,所有异常都可以由中间件调用。 In Asp.Net Core 5.0 Hub Filters will do that job.在 Asp.Net Core 5.0 中,集线器过滤器将完成这项工作。

But how to handle exceptions in Asp.Net Core 3.1 in SignalR hubs?但是如何在 SignalR 集线器中处理 Asp.Net Core 3.1 中的异常? Is there a sole way to write try/catch in every methods like below?有没有一种方法可以在下面的每种方法中编写 try/catch?

[Authorize]
public class OrdersHub : BaseHub
{
        public async Task GetOrder(Guid requestId, int orderId)
        {
            try
            {
                var data = await ordersService.GetOrderAsync(orderId);
                await Clients.Caller.SendAsync("GetOrderResult", requestId, result);
            }
            catch (Exception ex)
            {
                await Clients.Caller.Reject(requestId, ex);
            }
        }
}

You may know that ASP.NET SignalR has support for HubPipeline modules that provide a way to handle hub exceptions globally.您可能知道 ASP.NET SignalR 支持HubPipeline 模块,这些模块提供了一种全局处理集线器异常的方法。

But from this doc we can find HubPipeline modules is no longer supported in ASP.NET Core SignalR, and currently it seems not provide alternative approach to handle incomming errors globally.但是从这个文档中我们可以发现 ASP.NET Core SignalR 不再支持 HubPipeline 模块,目前它似乎没有提供替代方法来处理全局传入错误。

As you mentioned, we can wrap code in try-catch blocks and log the exception object or manually send it to caller.正如您提到的,我们可以将代码包装在 try-catch 块中并记录异常对象或手动将其发送给调用者。

Please note that exceptions often contain sensitive information, for security reasons sending detailed information to clients is not recommended in production.请注意,异常通常包含敏感信息,出于安全原因,不建议在生产中向客户端发送详细信息。

Besides, ASP.NET Core SignalR provides built-in diagnostics logging feature that could help capture and log useful transports and Hub related information, which could help troubleshoot the issue.此外,ASP.NET Core SignalR 提供了内置的诊断日志记录功能,可以帮助捕获和记录有用的传输和集线器相关信息,这可以帮助解决问题。

Note : you can check this github issue that discuss same requirement about "Signalr .net core central exception handling".注意:您可以查看讨论有关“Signalr .net 核心中央异常处理”的相同要求的github 问题

从 .net 5.0 开始,您可以使用集线器过滤器: https : //docs.microsoft.com/en-us/aspnet/core/signalr/hub-filters?view= aspnetcore-5.0

In my case, I wanted to log all unhandled exceptions thrown in my signalr hub.就我而言,我想记录在我的 signalr 集线器中抛出的所有未处理的异常。 I'm using .NET 6 and did the following.我正在使用 .NET 6 并执行了以下操作。

  1. Add ExceptionFilter.cs.添加 ExceptionFilter.cs。
public class ExceptionFilter : IHubFilter
{
    private readonly ILogger _logger;

    public ExceptionFilter(ILogger logger)
    {
        _logger = logger;
    }

    public async ValueTask<object> InvokeMethodAsync(
        HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next)
    {
        try
        {
            return await next(invocationContext);
        }
        catch (Exception ex)
        {
            _logger.LogError($"Exception calling '{invocationContext.HubMethodName}': {ex}");
            throw;
        }
    }
}
  1. Add ExceptionFilter to the signalr options.将 ExceptionFilter 添加到 signalr 选项。
builder.Services.AddSignalR(options =>
{
    options.AddFilter<ExceptionFilter>();
});
  1. Register ExceptionFilter for DI.为 DI 注册 ExceptionFilter。
builder.Services.AddSingleton<ExceptionFilter>();

I tested this by manually throwing an exception in a hub method, and the catch block gets executed.我通过在集线器方法中手动抛出异常来测试它,然后执行 catch 块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM