简体   繁体   中英

How to identify SignalR core hub errors on the JavaScript client?

We are trying to setup error handling on a SignalR Core invoke method from a JavaScript client that needs to identify the error's type and act accordingly (eg if it is an authorization error, the user should be prompted to log in, etc.).

We've determined that the error returned from the hub contains a message and a stack property and have build the following that sets an error code based on the text contained in the message property: 在此处输入图像描述

Will the error text always be returned in English (and can thus be used to identify the error)? Or is there a better way to go about achieving this?

We are using.Net Core 3.1 and @microsoft/signalr 3.1.10.

According to aspnetcore/SignalR server-side code on GitHub, it seems that the invocation errors are indeed passed by string value.

The method responsible for send back error are defined as follow:

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

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

And a few examples on how it is being called:

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);

The only information about error is the string parameter of errorMessage .

On the other hand, the 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."));
    
    ...
};

This indicates that "Invocation canceled due to the underlying connection being closed." is the default error message when none was provided by server.

Therefore, I believe if the SignalR team didn't change the error message sending mechanism, your string.includes approach is reasonable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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