Gestione degli errori in un'applicazione client / server

0

Sto sviluppando un'applicazione web e sto lottando per seguire una semantica chiara mentre restituisco la risposta al cliente. Prendendo un esempio di autenticazione di un utente ci possono essere gli scenari seguenti:

1. La richiesta ha esito positivo

L'utente è autenticato e invio una risposta JSON

{success: true} // and an optional message field?

2. Si è verificato un errore dell'applicazione

L'utente non è autenticato.

{error: true, message: 'Invalid email or password'} // Again I am not sure if I should let client decide to show the error message

3. Errore di sistema

Query SQL non valida, DB arrestato in modo anomalo, ecc. In genere il server deve restituire il codice di stato 500 , ma dovrei inviare di nuovo la risposta JSON? se sì, quanto dovrei dire al cliente? perché il client o l'utente potrebbero non essere interessati a sapere che DB si è arrestato in modo anomalo o SQL non è stato formattato correttamente.

Qualsiasi altro suggerimento / modifica è il benvenuto.

    
posta CodeYogi 08.06.2017 - 20:22
fonte

2 risposte

4

I am developing a web application and struggling to follow a clear semantic while returning response to the client. Taking an example of authenticating an user there can be following scenarios:

1. Request is successful

The user is authenticated and I send a JSON response

{success: true} // and an optional message field?

In caso di dubbio, D.R.Y.

Come cliente per un servizio REST, una 204 risposta vuota è abbastanza per indicare che tutto ha funzionato e che il cliente non ha bisogno di fare altro.

2. An application error occurred

User is not authenticated.

{error: true, message: 'Invalid email or password'} // Again I am not sure if I should let client decide to show the error message

Un client di solito si aspetta che gli errori di autenticazione / autorizzazione siano gestiti con una risposta 401 . Non sono necessarie ulteriori informazioni; infatti, meno informazioni fornite sono meno informazioni disponibili per un potenziale intruso che sta tentando di indovinare combinazioni di nome utente e password diverse.

Altri tipi di errori, come una stringa di query formattata in modo errato, errori nel corpo della richiesta HTTP o errori di convalida tipicamente restituiscono 400 Richiesta non valida .

Nel caso di 400 Bad Request, vale certamente la pena di restituire una risposta con informazioni dettagliate che descrivono esattamente come la richiesta potrebbe essere errata - se si tratta di un problema con la struttura dei dati, il formato dei dati, un campo mancante, un errore di convalida, alcune informazioni inaspettate, ecc.

Come cliente per un servizio REST, la qualità del messaggio e i dettagli forniti in una risposta di errore 400 possono essere la differenza tra ore / giorni di debug di tentativi ed errori frustranti rispetto a un rapido bugfix di 5 minuti.

3. System error

Bad SQL query, DB crashed etc. typically server should return 500 status code but should I again send the JSON response with it? if yes, how much should I tell the client? because the client or user may not be interested in knowing that DB crashed or SQL was not well formatted.

Un semplice errore interno del server 500 è tutto ciò che ti serve qui. Un client non può fare nulla per un bug nel codice del server, né il fatto che il database si sia bloccato o il server non sia riuscito in qualche modo inaspettato. Quando un cliente riceve "500" l'unica cosa sensata da fare per quel cliente è semplicemente rinunciare (e magari riprovare molto dopo ..)

Le informazioni sugli errori sul lato server sono importanti per chiunque si occupi del server, quindi il posto migliore per tali informazioni sono i log del server.

Il tempo speso nel tentativo di inviare informazioni a un client sarebbe molto meglio servito assicurando che i registri contengano informazioni dettagliate che consentano a qualcuno di eseguire il debug del server.

In generale

Non restituire i propri flag di stato degli errori JSON arrotolati a mano da un'API REST per scenari che sono già gestiti da codici di stato HTTP ben noti. Le librerie client HTTP sono generalmente già in grado di gestire tali codici di ritorno, quindi non solo stai potenzialmente reinventando la ruota sul server e rendendo la tua API inutilmente complessa con oggetti e campi aggiuntivi, probabilmente stai anche costringendo il client a fare lo stesso, e anche fare un lavoro extra non necessario sul lato client.

    
risposta data 08.06.2017 - 22:25
fonte
2

1 Utilizzo del codice di stato della risposta HTTP

Sia per comunicare una risposta di successo o di errore nelle applicazioni Web, è altamente desiderabile (dal punto di vista del cliente e dello sviluppatore) utilizzare Catalogo codice stato risposta HTTP . Spesso, flag come success:true o error:true sono indirizzati a fornire esattamente lo stesso feedback fornito dai codici di stato HTTP, con l'inconveniente di essere solo utili (o significativi) per noi.

Lo scopo dei flag è decidere se la richiesta HTTP è stata completata con successo o meno e dividere il codice in due possibili percorsi di esecuzione. Tuttavia, se utilizziamo il corretto codice di stato della risposta HTTP, troviamo che la maggior parte dei client HTTP lo fa già per noi.

AngularJS 1.5 (Jquery based) (Documentation)

$http.({...})
.then(function (response){
    // OK (2xx)
     ...
})
.catch(function (error){
    // KO (5xx , 4xx)
    ....
});

Jquery (Documentation)

$.ajax({...}) 
.done(function() {
  // OK (2xx)
})
.fail(function() {
   // KO (5xx , 4xx)
})  
.always(function() {
   // Both
});

2 messaggi di errore

Ho concordato che l'utente non ha bisogno di sapere che il DB si è bloccato. Di solito, questi errori sono rari, quindi un messaggio generico è tutto l'utente che deve sapere:

La richiesta non può essere elaborata a causa di errori interni. Per favore, provalo più tardi o contatta il .... .

Dal punto di vista della sicurezza, evitare di fornire la risposta con troppi dettagli. Alcuni dettagli potrebbero essere utilizzati per cercare vulnerabilità. Riducendo le informazioni possiamo anche ridurre la superficie di attacco.

Ritorno al 2 ° esempio, Invalid email or password . Questo è un buon esempio di un messaggio generico. Basta fare molto di più "web compliant" restituendo il messaggio con uno stato 401 codice.

3 Gestione dell'implementazione degli errori

Come restituire un messaggio personalizzato per ogni possibile errore (eccezione) dipende dal framework o dall'SDK. Tuttavia, l'approccio utilizzato è: intercettare l'errore il più tardi possibile . Diciamo, ad esempio, nel controller . Il controller di solito ha accesso alla risposta, quindi potremmo scrivere il messaggio personalizzato e il codice di stato HTTP da lì.

    
risposta data 08.06.2017 - 22:22
fonte

Leggi altre domande sui tag