Come iniziare

Gestione Errori

Come gestire errori e codici di stato nell'API

Questa guida ti aiuta a gestire correttamente gli errori quando utilizzi l'API Italianonprofit.

Formato Errori

Tutti gli errori seguono lo stesso formato standardizzato:

{
  "status": "error",
  "error": {
    "code": "CODICE_ERRORE",
    "message": "Messaggio di errore descrittivo",
    "details": {
      "campo": "Dettaglio specifico del campo"
    }
  },
  "meta": {
    "requestId": "uuid-unico",
    "timestamp": "2024-01-15T10:30:00.000Z"
  }
}

Codici Errore Comuni

Errori di Autenticazione

CodiceHTTPDescrizione
AUTHENTICATION_REQUIRED401Token mancante o non valido
TOKEN_EXPIRED401Token scaduto
INVALID_TOKEN401Token non valido o malformato
REFRESH_TOKEN_INVALID401Refresh token non valido

Errori di Autorizzazione

CodiceHTTPDescrizione
FORBIDDEN403Accesso negato
INSUFFICIENT_PERMISSIONS403Permessi insufficienti
SCOPE_NOT_ALLOWED403Scope API Key non permesso
RESOURCE_OWNERSHIP_REQUIRED403Non sei proprietario della risorsa

Errori di Validazione

CodiceHTTPDescrizione
VALIDATION_ERROR400Dati di input non validi
INVALID_PARAM400Parametro non valido
MISSING_REQUIRED_FIELD400Campo obbligatorio mancante
INVALID_FORMAT400Formato dati non valido

Errori di Risorsa

CodiceHTTPDescrizione
NOT_FOUND404Risorsa non trovata
RESOURCE_NOT_FOUND404Risorsa specifica non trovata
CONFLICT409Conflitto con stato attuale
DUPLICATE_RESOURCE409Risorsa già esistente

Errori di Server

CodiceHTTPDescrizione
INTERNAL_SERVER_ERROR500Errore interno del server
DATABASE_ERROR500Errore nel database
SERVICE_UNAVAILABLE503Servizio temporaneamente non disponibile
ELASTICSEARCH_UNAVAILABLE503Elasticsearch non disponibile

Esempi di Gestione Errori

JavaScript/TypeScript

async function makeRequest(url: string, options: RequestInit) {
  try {
    const response = await fetch(url, options);
    const data = await response.json();

    if (data.status === "error") {
      // Gestisci errore
      switch (data.error.code) {
        case "AUTHENTICATION_REQUIRED":
        case "TOKEN_EXPIRED":
          // Riloggare o rinnovare token
          await refreshToken();
          break;
        case "VALIDATION_ERROR":
          // Mostra errori di validazione all'utente
          showValidationErrors(data.error.details);
          break;
        case "NOT_FOUND":
          // Risorsa non trovata
          showNotFoundMessage();
          break;
        default:
          // Errore generico
          showErrorMessage(data.error.message);
      }
      throw new Error(data.error.message);
    }

    return data.data;
  } catch (error) {
    // Gestisci errori di rete o altri errori
    console.error("Request failed:", error);
    throw error;
  }
}

Python

import requests

def make_request(url, headers=None, data=None):
    try:
        response = requests.post(url, headers=headers, json=data)
        response.raise_for_status()

        result = response.json()

        if result.get('status') == 'error':
            error = result.get('error', {})
            error_code = error.get('code')

            if error_code == 'AUTHENTICATION_REQUIRED':
                # Riloggare o rinnovare token
                refresh_token()
            elif error_code == 'VALIDATION_ERROR':
                # Mostra errori di validazione
                print(f"Validation errors: {error.get('details')}")
            else:
                print(f"Error: {error.get('message')}")

            raise Exception(error.get('message'))

        return result.get('data')
    except requests.exceptions.HTTPError as e:
        print(f"HTTP error: {e}")
        raise

Gestione Errori Specifici

Token Scaduto

Quando un token è scaduto, devi rinnovarlo usando il refresh token:

if (error.code === "TOKEN_EXPIRED") {
  const newToken = await refreshAccessToken(refreshToken);
  // Riprova la richiesta con il nuovo token
  return await retryRequest(url, newToken);
}

Errori di Validazione

Gli errori di validazione includono dettagli sui campi specifici:

{
  "status": "error",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "I dati forniti non sono validi",
    "details": {
      "email": "Email non valida",
      "password": "Password deve contenere almeno 8 caratteri"
    }
  }
}

Usa questi dettagli per mostrare errori specifici nel form:

if (error.code === "VALIDATION_ERROR" && error.details) {
  Object.entries(error.details).forEach(([field, message]) => {
    setFieldError(field, message);
  });
}

Rate Limiting

Se superi i limiti di rate, riceverai:

{
  "status": "error",
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Troppe richieste. Riprova più tardi.",
    "details": {
      "retryAfter": 60
    }
  }
}

Implementa un backoff esponenziale:

if (error.code === "RATE_LIMIT_EXCEEDED") {
  const retryAfter = error.details?.retryAfter || 60;
  await sleep(retryAfter * 1000);
  return await retryRequest(url, options);
}

Best Practices

  1. Sempre controlla status prima di accedere a data
  2. Usa requestId per tracciare problemi in produzione
  3. Logga errori con tutti i dettagli per debugging
  4. Mostra messaggi user-friendly basati su message
  5. Implementa retry logic per errori temporanei (5xx)
  6. Non ritentare errori client (4xx) senza modificare la richiesta
  7. Gestisci timeout e errori di rete separatamente

Debugging

Per aiutare il debugging, ogni errore include:

  • requestId: UUID univoco per tracciare la richiesta nei log
  • timestamp: Quando si è verificato l'errore
  • code: Codice standardizzato per identificare il tipo di errore
  • details: Informazioni aggiuntive quando disponibili

Se hai bisogno di supporto, fornisci sempre il requestId quando contatti il supporto.

Prossimi Passi