Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.
Varning
Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i supportpolicyn för .NET och .NET Core. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.
I den här artikeln beskrivs felhantering och gRPC:
- Inbyggda funktioner för felhantering med hjälp av gRPC-statuskoder och felmeddelanden.
- Skicka komplex, strukturerad felinformation med hjälp av omfattande felhantering.
Inbyggd felhantering
gRPC-anrop kommunicerar lyckade eller misslyckade utfall med en statuskod. När ett gRPC-anrop har slutförts returnerar servern en OK status till klienten. Om ett fel inträffar returnerar gRPC:
- En felstatuskod, till exempel
CANCELLEDellerUNAVAILABLE. - Ett valfritt strängfelmeddelande.
De typer som ofta används med felhantering är:
-
StatusCode: En uppräkning av gRPC-statuskoder.OKsignalerar framgång; andra värden innebär misslyckande. -
Status: Astructsom kombinerar ettStatusCodeoch ett valfritt strängfelmeddelande. Felmeddelandet innehåller ytterligare information om vad som hände. -
RpcException: En undantagstyp som harStatusett värde. Det här undantaget genereras i gRPC-servermetoder och fångas av gRPC-klienter.
Inbyggd felhantering stöder endast en statuskod och en strängbeskrivning. Om du vill skicka komplex felinformation från servern till klienten använder du omfattande felhantering.
Utlösa serverfel
Ett gRPC-serveranrop returnerar alltid status. Servern returnerar OK automatiskt när en metod har slutförts.
public class GreeterService : GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}" });
}
public override async Task SayHelloStreaming(HelloRequest request,
IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
for (var i = 0; i < 5; i++)
{
await responseStream.WriteAsync(new HelloReply { Message = $"Hello {request.Name} {i}" });
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
}
Föregående kod:
- Implementerar den unära metoden
SayHellosom slutförs framgångsrikt när den returnerar ett svarsmeddelande. - Implementerar serverströmningsmetoden
SayHelloStreamingsom framgångsrikt slutförs när metoden är klar.
Serverfelstatus
gRPC-metoder returnerar en felstatuskod genom att utlösa ett undantag. När en RpcException genereras på servern returneras dess statuskod och beskrivning till klienten:
public class GreeterService : GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
if (string.IsNullOrEmpty(request.Name))
{
throw new RpcException(new Status(StatusCode.InvalidArgument, "Name is required."));
}
return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}" });
}
}
Undantagstyper som inte RpcException också orsakar att anropet misslyckas, men med en UNKNOWN statuskod och ett allmänt meddelande Exception was thrown by handler.
Exception was thrown by handler skickas till klienten i stället för undantagsmeddelandet för att förhindra att potentiellt känslig information exponeras. Om du vill se ett mer beskrivande felmeddelande i en utvecklingsmiljö konfigurerar du EnableDetailedErrors.
Hantera klientfel
När en gRPC-klient gör ett anrop verifieras statuskoden automatiskt när svaret nås. Om du till exempel väntar på ett unary gRPC-anrop returneras meddelandet som skickas av servern om anropet lyckas och utlöser ett RpcException om det uppstår ett fel. Hantera RpcException för att fånga fel i en klient:
var client = new Greet.GreeterClient(channel);
try
{
var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });
Console.WriteLine("Greeting: " + response.Message);
}
catch (RpcException ex)
{
Console.WriteLine("Status code: " + ex.Status.StatusCode);
Console.WriteLine("Message: " + ex.Status.Detail);
}
Föregående kod:
- Gör ett unary gRPC-anrop till
SayHellometoden. - Skriver svarsmeddelandet till konsolen om det lyckas.
- Upptäcker
RpcExceptionoch skriver ut felinformation vid misslyckande.
Felscenarier
Fel representeras av RpcException med en felstatuskod och ett valfritt informationsmeddelande.
RpcException genereras i många scenarier:
- Anropet misslyckades på servern och servern skickade en felstatuskod. Till exempel startade gRPC-klienten ett anrop som saknade nödvändiga data från begärandemeddelandet och servern returnerar en
INVALID_ARGUMENTstatuskod. - Ett fel uppstod i klienten när gRPC-anropet gjordes. En klient gör till exempel ett gRPC-anrop, kan inte ansluta till servern och utlöser ett fel med statusen
UNAVAILABLE. - Det CancellationToken som skickas till gRPC-anropet avbryts. GRPC-anropet stoppas och klienten genererar ett fel med statusen
CANCELLED. - Ett gRPC-anrop överskrider den konfigurerade tidsgränsen. GRPC-anropet stoppas och klienten genererar ett fel med statusen
DEADLINE_EXCEEDED.
Omfattande felhantering
Omfattande felhantering gör att komplex, strukturerad information kan skickas med felmeddelanden. Till exempel validering av inkommande meddelandefält som returnerar en lista med ogiltiga fältnamn och beskrivningar.
Felmodellengoogle.rpc.Status används ofta för att skicka komplex felinformation mellan gRPC-appar.
gRPC på .NET stöder en omfattande felmodell med hjälp av Grpc.StatusProto paketet. Det här paketet har metoder för att skapa omfattande felmodeller på servern och läsa dem av en klient. Den omfattande felmodellen bygger på gRPC:s inbyggda hanteringsfunktioner och kan användas sida vid sida.
Viktigt!
Fel ingår i rubriker och de totala rubrikerna i svar är ofta begränsade till 8 KB (8 192 byte). Kontrollera att rubrikerna som innehåller fel inte överskrider 8 KB.
Skapa omfattande fel på servern
Omfattande fel skapas från Google.Rpc.Status. Den här typen skiljer sig från Grpc.Core.Status.
Google.Rpc.Status har fälten status, meddelande och information. Det viktigaste fältet är information, vilket är ett upprepande fält med Any värden. Information är var komplexa nyttolaster läggs till.
Även om alla meddelandetyper kan användas som en nyttolast rekommenderar vi att du använder någon av standardfelnyttolasterna:
BadRequestPreconditionFailureErrorInfoResourceInfoQuotaFailure
Grpc.StatusProto
ToRpcException innehåller en hjälpfunktion för att omvandla Google.Rpc.Status till ett fel. Generera felet från gRPC-servermetoden:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
ArgumentNotNullOrEmpty(request.Name);
return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
}
public static void ArgumentNotNullOrEmpty(string value, [CallerArgumentExpression(nameof(value))] string? paramName = null)
{
if (string.IsNullOrEmpty(value))
{
var status = new Google.Rpc.Status
{
Code = (int)Code.InvalidArgument,
Message = "Bad request",
Details =
{
Any.Pack(new BadRequest
{
FieldViolations =
{
new BadRequest.Types.FieldViolation { Field = paramName, Description = "Value is null or empty" }
}
})
}
};
throw status.ToRpcException();
}
}
}
Avläsning av detaljerade fel från en klient
Detaljerade fel läses från RpcException som fångas av klienten. Fånga undantaget och använd hjälpmetoder som tillhandahålls av Grpc.StatusCode för att hämta dess Google.Rpc.Status instans:
var client = new Greet.GreeterClient(channel);
try
{
var reply = await client.SayHelloAsync(new HelloRequest { Name = name });
Console.WriteLine("Greeting: " + reply.Message);
}
catch (RpcException ex)
{
Console.WriteLine($"Server error: {ex.Status.Detail}");
var badRequest = ex.GetRpcStatus()?.GetDetail<BadRequest>();
if (badRequest != null)
{
foreach (var fieldViolation in badRequest.FieldViolations)
{
Console.WriteLine($"Field: {fieldViolation.Field}");
Console.WriteLine($"Description: {fieldViolation.Description}");
}
}
}
Föregående kod:
- Gör ett gRPC-anrop i en try/catch som fångar
RpcException. - Anropar
GetRpcStatus()för att försöka få fram den fylliga felmodellen från undantaget. - Anrop
GetDetail<BadRequest>()för att försöka hämta enBadRequestnyttolast från det omfattande felet.
Ytterligare resurser
ASP.NET Core