Mappare gli Errori sui Codici di Stato del Trasporto
Una volta definiti i tuoi errori nel DSL di Goa, il passo successivo è mappare questi errori su appropriati codici di stato specifici del trasporto. Questo assicura che i client ricevano risposte significative e standardizzate basate sulla natura dell’errore. Goa ti permette di definire queste mappature per diversi protocolli di trasporto, come HTTP e gRPC, usando la funzione Response all’interno del DSL.
Mappatura del Trasporto HTTP
Per i trasporti HTTP, usi la funzione HTTP all’interno delle tue definizioni di servizio o metodo per mappare gli errori su specifici codici di stato HTTP. Questa mappatura assicura che quando si verifica un errore, il client riceva una risposta HTTP con il corretto codice di stato e le informazioni sull’errore.
Esempio
var _ = Service("divider", func() {
Error("DivByZero", func() {
Description("DivByZero è l'errore restituito quando il divisore è zero.")
})
HTTP(func() {
// Mappa l'errore "DivByZero" su HTTP 400 Bad Request
Response("DivByZero", StatusBadRequest)
})
Method("integral_divide", func() {
Error("HasRemainder", func() {
Description("HasRemainder viene restituito quando una divisione intera ha un resto.")
})
HTTP(func() {
// Mappa l'errore "HasRemainder" su HTTP 417 Expectation Failed
Response("HasRemainder", StatusExpectationFailed)
})
// Definizioni aggiuntive del metodo...
})
Method("divide", func() {
// Definizioni specifiche del metodo...
})
})
In questo esempio:
DivByZero: Mappato sul codice di stato HTTP 400 Bad Request.HasRemainder: Mappato sul codice di stato HTTP 417 Expectation Failed.
Definire le Risposte
All’interno della funzione HTTP, usi la funzione Response per associare ogni errore con un codice di stato HTTP. La sintassi è la seguente:
Response("<NomeErrore>", <CodiceStatoHTTP>, func() {
Description("<Descrizione opzionale>")
})
<NomeErrore>: Il nome dell’errore come definito nel DSL.<CodiceStatoHTTP>: Il codice di stato HTTP su cui mappare l’errore.Description: (Opzionale) Una descrizione della risposta per scopi di documentazione.
Esempio Completo di Mappatura HTTP
var _ = Service("divider", func() {
// Errori a livello di servizio
Error("DivByZero", func() {
Description("DivByZero è l'errore restituito quando il divisore è zero.")
})
HTTP(func() {
// Mappature degli errori a livello di servizio
Response("DivByZero", StatusBadRequest) // 400
})
Method("integral_divide", func() {
Description("Esegue la divisione intera e controlla i resti")
Payload(func() {
Field(1, "dividend", Int, "Numero da dividere")
Field(2, "divisor", Int, "Numero per cui dividere")
Required("dividend", "divisor")
})
Result(Int)
Error("HasRemainder", func() {
Description("HasRemainder viene restituito quando una divisione intera ha un resto.")
})
HTTP(func() {
POST("/divide/integral")
// Mappatura degli errori specifica del metodo
Response("HasRemainder", StatusExpectationFailed, func() { // 417
Description("Restituito quando la divisione risulta in un resto")
})
})
})
Method("divide", func() {
Description("Esegue la divisione in virgola mobile")
Payload(func() {
Field(1, "dividend", Float64, "Numero da dividere")
Field(2, "divisor", Float64, "Numero per cui dividere")
Required("dividend", "divisor")
})
Result(Float64)
Error("Overflow", func() {
Description("Overflow viene restituito quando il risultato supera il valore massimo.")
})
HTTP(func() {
POST("/divide")
// Mappatura degli errori specifica del metodo
Response("Overflow", StatusUnprocessableEntity, func() { // 422
Description("Restituito quando il risultato della divisione supera il valore massimo")
})
})
})
})
Questo esempio dimostra:
Errori a Livello di Servizio: Errori comuni che si applicano attraverso i metodi:
DivByZero: Quando si tenta di dividere per zero
Errori Specifici del Metodo: Ogni metodo definisce i propri errori specifici:
integral_divide: Gestisce i casi con restodivide: Gestisce l’overflow in virgola mobile
Mappatura dei Codici di Stato HTTP:
- 400 Bad Request: Per la divisione per zero
- 417 Expectation Failed: Per la divisione intera con resto
- 422 Unprocessable Entity: Per l’overflow in virgola mobile
Endpoint Diversi: Mostra la mappatura degli errori per due diverse operazioni di divisione:
/divide/integralper la divisione intera/divideper la divisione in virgola mobile
Le mappature assicurano che ogni condizione di errore restituisca un codice di stato HTTP appropriato che riflette accuratamente la natura dell’errore.
Mappatura del Trasporto gRPC
Per i trasporti gRPC, usi la funzione GRPC all’interno delle tue definizioni di servizio o metodo per mappare gli errori su specifici codici di stato gRPC. Questa mappatura assicura che quando si verifica un errore, il client riceva una risposta gRPC con il corretto codice di stato e le informazioni sull’errore.
Esempio
var _ = Service("divider", func() {
Error("DivByZero", func() {
Description("DivByZero è l'errore restituito quando il divisore è zero.")
})
GRPC(func() {
// Mappa l'errore "DivByZero" sul codice di stato gRPC InvalidArgument (3)
Response("DivByZero", CodeInvalidArgument)
})
Method("integral_divide", func() {
Error("HasRemainder", func() {
Description("HasRemainder viene restituito quando una divisione intera ha un resto.")
})
GRPC(func() {
// Mappa l'errore "HasRemainder" sul codice di stato gRPC Unknown (2)
Response("HasRemainder", CodeUnknown)
})
// Definizioni aggiuntive del metodo...
})
Method("divide", func() {
// Definizioni specifiche del metodo...
})
})
In questo esempio:
DivByZero: Mappato sul codice di stato gRPC InvalidArgument (codice 3).HasRemainder: Mappato sul codice di stato gRPC Unknown (codice 2).
Definire le Risposte
All’interno della funzione GRPC, usi la funzione Response per associare ogni errore con un codice di stato gRPC. La sintassi è la seguente:
Response("<NomeErrore>", Code<CodiceStato>, func() {
Description("<Descrizione opzionale>")
})
<NomeErrore>: Il nome dell’errore come definito nel DSL.Code<CodiceStato>: Il codice di stato gRPC su cui mappare l’errore, prefissato con Code.Description: (Opzionale) Una descrizione della risposta per scopi di documentazione.
Combinare le Mappature HTTP e gRPC
Goa ti permette di definire sia mappature HTTP che gRPC all’interno dello stesso servizio o metodo. Questo è particolarmente utile quando il tuo servizio supporta trasporti multipli, assicurando che gli errori siano mappati appropriatamente indipendentemente dal protocollo di trasporto utilizzato dal client.
Esempio
var _ = Service("divider", func() {
Error("DivByZero", func() {
Description("DivByZero viene restituito quando si tenta di dividere per zero.")
})
Method("divide", func() {
Payload(func() {
Field(1, "dividend", Float64, "Numero da dividere")
Field(2, "divisor", Float64, "Numero per cui dividere")
Required("dividend", "divisor")
})
Result(Float64)
HTTP(func() {
POST("/divide")
// Mappa la divisione per zero su HTTP 422 Unprocessable Entity
Response("DivByZero", StatusUnprocessableEntity)
})
GRPC(func() {
// Mappa la divisione per zero su INVALID_ARGUMENT
Response("DivByZero", CodeInvalidArgument)
})
})
})