Gestione degli errori GraphQL
L'API GraphQL di Riseact utilizza due meccanismi distinti per comunicare gli errori, a seconda del contesto in cui si verificano.
Due tipi di errore
| Tipo | Dove appare | Quando si usa |
|---|---|---|
userErrors | Nel payload della mutation | Errori di validazione e business logic |
errors (GraphQL) | In cima alla risposta | Errori strutturali, risorsa non trovata, permessi |
1. userErrors — errori di validazione
Le mutation restituiscono sempre un oggetto response che include un campo userErrors. Questo campo è null in caso di successo, oppure contiene una lista di errori se l'operazione non è andata a buon fine.
Struttura:
type UserError {
code: ErrorCode!
field: String # campo specifico che ha causato l'errore, se applicabile
message: String # descrizione leggibile
}
enum ErrorCode {
BAD_INPUT # input non valido o mancante
NOT_FOUND # risorsa non trovata
NOT_UNIQUE # violazione di unicità
PROTECTED # eliminazione bloccata da dipendenze
}
Esempio di risposta con errore:
{
"data": {
"supporterCreate": {
"supporter": null,
"userErrors": [
{
"code": "BAD_INPUT",
"field": "email",
"message": "This field is required."
}
]
}
}
}
Esempio di risposta con successo:
{
"data": {
"supporterCreate": {
"supporter": {
"id": 42,
"email": "mario@example.com"
},
"userErrors": null
}
}
}
Come gestire userErrors
Controlla sempre userErrors dopo ogni mutation prima di usare i dati restituiti:
const { data } = await client.mutate({ mutation: CREATE_SUPPORTER, variables });
if (data.supporterCreate.userErrors?.length) {
const errors = data.supporterCreate.userErrors;
// gestisci gli errori per campo
errors.forEach(err => {
console.error(`[${err.code}] ${err.field}: ${err.message}`);
});
return;
}
const supporter = data.supporterCreate.supporter;
2. Errori GraphQL — eccezioni strutturali
Alcuni errori non vengono intercettati nel payload della mutation ma propagano come errori GraphQL standard, nell'array errors della risposta.
Casi comuni:
| Situazione | Tipo di errore |
|---|---|
| Risorsa non trovata in una query | GraphqlNotFound |
| Token non valido o mancante | errore di autenticazione |
| Permessi insufficienti | errore di autorizzazione |
| Query malformata | errore di parsing |
Esempio di risposta:
{
"data": null,
"errors": [
{
"message": "Resource not found",
"locations": [{ "line": 2, "column": 3 }],
"path": ["donation"]
}
]
}
L'HTTP status code è quasi sempre 200 anche in presenza di errori GraphQL. Controlla sempre il campo errors nella risposta, non solo lo status HTTP.
Come gestire gli errori GraphQL
const response = await client.query({ query: GET_DONATION, variables: { id: 999 } });
if (response.errors?.length) {
const message = response.errors[0].message;
// es. "Resource not found"
console.error('GraphQL error:', message);
return;
}
Riepilogo del pattern consigliato
async function safeMutate(client, mutation, variables) {
let response;
try {
response = await client.mutate({ mutation, variables });
} catch (networkError) {
// Errore di rete o HTTP 5xx
throw new Error('Network error: ' + networkError.message);
}
// Errori strutturali GraphQL
if (response.errors?.length) {
throw new Error('GraphQL error: ' + response.errors[0].message);
}
// Errori di business logic nella mutation
const rootKey = Object.keys(response.data)[0];
const result = response.data[rootKey];
if (result.userErrors?.length) {
throw new Error('Validation error: ' + result.userErrors[0].message);
}
return result;
}