typescript - Hur identifierar man SignalR core-hubbfel på JavaScript-klienten?
Vi försöker sätta upp felhantering på en SignalR Core-invokationsmetod från en JavaScript-klient som behöver identifiera feltypen och agera därefter (t.ex. om det är ett auktoriseringsfel, ska användaren uppmanas att logga in, etc.).
Vi har fastställt att felet som returneras från hubben innehåller ett meddelande och en stack-egenskap och har byggt följande som sätter en felkod baserat på texten i meddelandeegenskapen:
Kommer feltexten alltid att returneras på engelska (och kan därför användas för att identifiera felet)? Eller finns det ett bättre sätt att uppnå detta?
Vi använder .Net Core 3.1 och @microsoft/signalr 3.1.10.
Svar #1
Enligt aspnetcore/SignalR server-sida kod på GitHub verkar det som att anropsfel faktiskt vidarebefordras som strängvärde.
Metoden som är ansvarig för att skicka tillbaka fel definieras som följer:
private async Task SendInvocationError(string invocationId, HubConnectionContext connection, string errorMessage)
{
if (string.IsNullOrEmpty(invocationId))
{
return;
}
await connection.WriteAsync(CompletionMessage.WithError(invocationId, errorMessage));
}
Och några exempel på hur det kallas:
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);
Den enda informationen om fel är strängparametern för errorMessage.
Å andra sidan, klient-sidans JavaScript-biblioteks källkod:
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."));
...
};
Detta indikerar att "Invocation canceled due to the underlying connection being closed." är standardfelmeddelandet när inget meddelande tillhandahölls av servern.
Därför tror jag att om SignalR-teamet inte ändrade mekanismen för att skicka felmeddelanden, är ditt string.includes-tillvägagångssätt rimligt.
