Quale livello introdurre messaggi di errore leggibili dall'uomo?

6

Una delle cose di cui non sono mai stato soddisfatto in nessun progetto su cui ho lavorato nel corso degli anni e che non sono stato in grado di risolvere personalmente è esattamente in quale livello di un'applicazione devono essere recuperate le informazioni di errore leggibili dall'uomo per la visualizzazione a un utente.

Un approccio comune che ha funzionato bene è stato restituire "oggetti risultato" strongmente tipizzati / concreti dai metodi sulla superficie pubblica del livello aziendale / API. Un metodo sull'interfaccia potrebbe essere:

public ClearUserAccountsResult ClearUserAccounts(ClearUserAccountsParam param);

E l'implementazione della classe di risultati:

public class ClearUserAccountsResult : IResult
{
    public readonly List<Account> ClearedAccounts{get; set;}

    public readonly bool Success {get; set;}    // Implements IResult
    public readonly string Message{get; set;}   // Implements IResult, human readable

    // Constructor implemented here to set readonly properties...
}

Funziona alla grande quando l'API deve essere esposta su WCF poiché l'oggetto risultato può essere serializzato. Ancora una volta questo viene fatto solo sulla superficie pubblica del livello API / business. Il messaggio di errore può anche essere cercato dal database, il che significa che può essere modificato e localizzato.

Tuttavia, è sempre stato sospetto per me, questa idea di restituire informazioni leggibili dal livello aziendale come questo, in parte perché ciò che costituisce la superficie pubblica dell'API può cambiare nel tempo ... e potrebbe essere il caso che l'API dovrà essere riutilizzata da altri componenti API in futuro che non necessitano dei messaggi di stringa leggibili dall'uomo (e cercarli da un database sarebbe uno spreco costoso).

Penso che un approccio migliore sia quello di mantenere gli oggetti di business liberi da tali oggetti risultanti e mantenerli semplici e quindi recuperare stringhe di errore leggibili dall'uomo in qualche modo più vicino al livello dell'interfaccia utente o solo nell'interfaccia utente stessa, ma qui ho due problemi :

1) L'interfaccia utente può essere un client remoto (Winforms / WPF / Silverlight) o un'applicazione Web ASP.NET ospitata su un altro server. In questi casi l'interfaccia utente dovrà recuperare le stringhe di errore dal server.

2) Spesso ci sono molteplici modi legittimi di fallimento. Se il livello aziendale diventa così vago e generico nel modo in cui restituisce errori, potrebbero non esserci sufficienti informazioni esposte pubblicamente per indicare l'errore effettivo: es .: se un metodo ha 3 modi di errore legittimo ma restituisce un valore booleano per indicare un errore, non puoi capire quale dovrebbe essere il messaggio appropriato da mostrare all'utente.

Ho pensato di usare le enumerazioni fallite come sostituto, possono indicare un errore specifico che può essere testato e codificato. A volte ciò è utile all'interno del livello aziendale in quanto un modo di passare tramite il metodo restituisce le specifiche di un errore piuttosto che solo un valore booleano, ma non è così buono per gli scenari di serializzazione.

C'è uno schema ben indossato per questo? Cosa pensa la gente?

Grazie.

    
posta MrLane 06.11.2013 - 15:58
fonte

2 risposte

5

Suggerirei di creare un'API ben definita con un insieme chiaramente definito di risultati di errore per ciascun metodo esposto per i seguenti dubbi:

  • un'API non dovrebbe essere progettata attorno al consumatore. Dovrebbe definire un comportamento chiaro e cancellare i codici di errore. Il tuo chiamante potrebbe essere un'interfaccia utente, un servizio o un'altra API. Il chiamante deve decidere cosa fare in caso di errore e se è necessaria persino una presentazione.
  • Il consumatore potrebbe aver bisogno di più o meno "messaggi" a seconda del proprio scenario. Riportare la presentazione al consumatore consente la massima flessibilità nella presentazione.
  • Qualsiasi problema di localizzazione o lingua dovrebbe essere risolto dal consumatore e non dall'API.
risposta data 06.11.2013 - 18:49
fonte
0

A common approach that has worked well has been to return strongly typed/concrete "result objects" from the methods on the public surface of the business tier/API.

Che collega strettamente le tue opinioni con i tuoi modelli di dati. Facendo sì che il client si interrompa quando tali oggetti vengono modificati. È necessario considerare i client come un motore per il rendering dei modelli e inviare solo i dati per tali modelli al client. Questi dati dovrebbero essere il più generici possibile per soddisfare le esigenze dei modelli.

This works great when the API needs to be exposed over WCF as the result object can be serialized.

Sì serializzato, ma non considerarlo come una risposta oggetto ma come valori di dati per il tuo modello di visualizzazione . La vista dovrebbe essere un rendering senza logica di quei dati. Quanto è logico il modo in cui le visualizzazioni dipendono dal modo in cui i client vengono collegati al back-end, ma meno logica è, meglio è.

1) The UI may be a remote client (Winforms/WPF/Silverlight) or an ASP.NET web application hosted on another server. In these cases the UI will have to fetch the error strings from the server.

Vorrei inviare il messaggio insieme alla risposta dal server al client. Perché inviare un codice di risposta e chiedere al client di interrogarsi sul significato del codice? Questo non è il lavoro del cliente. Il client dovrebbe fare il minor lavoro possibile per rendere la visualizzazione per l'utente.

2) Often there are multiple legitimate modes of failure. If the business tier becomes so vague and generic in the way it returns errors there may not be enough information exposed publicly to tell what the error actually was: i.e: if a method has 3 modes of legitimate failure but returns a boolean to indicate failure, you cannot work out what the appropriate message to display to the user should be.

Manca qualcosa qui. Ci dovrebbe essere un elemento intermedio tra i modelli di dati e la vista client. Spesso indicato come il controller. Quella parte centrale interrogherà i modelli di dati per fare il lavoro, ricevere un codice di risposta, prendere quel codice e cercare un messaggio leggibile dall'uomo e poi inviarlo al client per la visualizzazione.

Is there a well worn pattern for this?

Si chiama Pattern View Controller (MVC).

link

link

C'è anche qualcosa chiamato MVVM (Model View ViewModel).

link

Ho scoperto che a volte devi implementare MVC sul server e MVVM su un client.

    
risposta data 06.11.2013 - 17:37
fonte

Leggi altre domande sui tag