【问题标题】:How to identify SignalR core hub errors on the JavaScript client?如何识别 JavaScript 客户端上的 SignalR 核心集线器错误?
【发布时间】:2020-11-25 09:46:31
【问题描述】:

我们正在尝试对来自 JavaScript 客户端的 SignalR Core 调用方法设置错误处理,该方法需要识别错误类型并采取相应措施(例如,如果是授权错误,则应提示用户登录等。 )。

我们已确定从集线器返回的错误包含消息和堆栈属性,并构建了以下内容,根据消息属性中包含的文本设置错误代码:

错误文本是否总是以英文返回(因此可用于识别错误)?还是有更好的方法来实现这一目标?

我们正在使用 .Net Core 3.1 和 @microsoft/signalr 3.1.10。

【问题讨论】:

  • 这是个好问题。直到今天我还没有找到像你这样的问题的任何解决方案。

标签: javascript typescript signalr asp.net-core-3.1 asp.net-core-signalr


【解决方案1】:

根据GitHub上的aspnetcore/SignalR server-side code,看来调用错误确实是通过字符串值传递的。

负责返回错误的方法定义如下:

private async Task SendInvocationError(string invocationId, HubConnectionContext connection, string errorMessage)
{
    if (string.IsNullOrEmpty(invocationId))
    {
        return;
    }

    await connection.WriteAsync(CompletionMessage.WithError(invocationId, errorMessage));
}

还有一些关于如何调用它的示例:

if (!await IsHubMethodAuthorized(scope.ServiceProvider, connection, descriptor, hubMethodInvocationMessage.Arguments, hub))
{
    Log.HubMethodNotAuthorized(_logger, hubMethodInvocationMessage.Target);
    await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection,
        $"Failed to invoke '{hubMethodInvocationMessage.Target}' because user is unauthorized");
    return;
}
var errorMessage = ErrorMessageHelper.BuildErrorMessage($"Failed to invoke '{bindingFailureMessage.Target}' due to an error on the server.",
    bindingFailureMessage.BindingFailure.SourceException, _enableDetailedErrors);
return SendInvocationError(bindingFailureMessage.InvocationId, connection, errorMessage);

关于错误的唯一信息是errorMessage的字符串参数。

另一方面,client-side javascript library source code:

HubConnection.prototype.connectionClosed = function (error) {
    this.logger.log(_ILogger__WEBPACK_IMPORTED_MODULE_2__["LogLevel"].Debug, "HubConnection.connectionClosed(" + error + ") called while in state " + this.connectionState + ".");
    // Triggering this.handshakeRejecter is insufficient because it could already be resolved without the continuation having run yet.
    this.stopDuringStartError = this.stopDuringStartError || error || new Error("The underlying connection was closed before the hub handshake could complete.");
    // If the handshake is in progress, start will be waiting for the handshake promise, so we complete it.
    // If it has already completed, this should just noop.
    if (this.handshakeResolver) {
        this.handshakeResolver();
    }
    this.cancelCallbacksWithError(error || new Error("Invocation canceled due to the underlying connection being closed."));
    
    ...
};

这表明"Invocation canceled due to the underlying connection being closed." 是服务器未提供任何错误消息时的默认错误消息。

因此,我相信如果 SignalR 团队没有更改错误消息发送机制,您的string.includes 方法是合理的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 2016-05-17
    相关资源
    最近更新 更多