Gestione e gestione dei codici di errore [chiuso]

4

Sto cercando esempi di creazione, gestione e gestione di numeri / codici di errore.

Per capire di cosa sto parlando, prendiamo uno scenario di esempio: (UE - utente finale, IT - helpdesk)

EU: - (calls IT) something's wrong
IT: - what happened?
EU: - it says "cannot create xyz"
IT: - what have you done?
EU: - ummm....
(conversation continues for another gazillion years)

... e l'eccezione che produce il messaggio cannot create xyz viene lanciata in dozzina di posti nell'intero sistema, quindi il tizio IT non sa dove cercare.

Un altro approccio (che mi piace davvero e vorrei usare) è ad esempio:

Ora,quandol'UEchiamaIT,l'interaconversazioneapparecosì:

EU:-Ihaveerror1004IT:-ok,thanks,we'lltakealook

Avendouncodicedierrore,ilragazzoITsaimmediatamentedovecercarel'errore.Nonhabisognodichiedereall'UEdiforniremoltidettaglifuorvianti,puòsemplicementesedersielavorareo,sesaperché,spiegarechesitrattadiunerroreintenzionaleperchél'UEhafattoqualcosadisbagliato.

Sembrafiorieciambelle,vero?

Maqualisonolemiglioripraticheperottenerequestocomportamento?

SupponiamochequestosiaJavaestiamocostruendoappdazero.Quellochesofinoraèchenonriescoaottenereicodicidierroredaldatabase,perchésevienelanciataun'eccezione,nonpossofareaffidamentosufontiesterne.

Questoportaaproblemiconillavorodisquadra.DiciamocheJohn,PauleAdampresumonocheuserannoicodicidierroredurantelascritturadellaloroappegenererannoerroriinmodoincrementale.VedolapossibilecollisionequandoJohnvuolemarcareilmessaggiodieccezionenelcodiceusandoilnumero#256,maPaulnonlosaecrealasuaeccezione,anchecon#256,eusaquestaeccezioneinpochedozzinediluoghiinapp.Allafinedellagiornatanessunosacosasignifichiveramentel'errore#256.

Quindiforsec'èunaltroapproccio:utilizzareunapiccolamapraticaappwebauntavolochegestiràlagenerazionedinumeridierrore,quindiJohn,PauleAdampossonosemplicementefareclicsu"Genera" quando vogliono un nuovo numero di errore univoco?

Sopra elaborato porta anche a un'altra domanda: quali sono le migliori pratiche per impostare i codici di errore? Eccezionalmente, in questo modo:

public class FooException extends Exception {
  public FooException() { super(); }
  public FooException(String message) { super("Error #256 - xyz is forbidden"); }
  public FooException(String message, Throwable cause) { super("Error #256 - xyz is forbidden", cause); }
  public FooException(Throwable cause) { super(cause); }
}

o

try{
    (some stuff)
} catch (FooException ex){
    System.out.println("Error #256 - you cannot do xyz in here");
}

Sospetto che la seconda opzione sia migliore, perché indica un posto univoco e specifico nel codice nell'intero progetto, ma sembra più difficile da gestire.

Qualche idea? Qualche pratica? Consigli? Grazie.

    
posta ex3v 08.09.2014 - 11:56
fonte

3 risposte

3

Vai avanti e utilizza i numeri di errore se vuoi utilizzare una tabella di riferimento, ma ti consiglio un approccio diverso.

Nel tuo messaggio informa l'utente:

  1. Che errore si è verificato. Se si tratta di un errore intenzionale generato a causa dell'input dell'utente, comunica loro cosa hanno sbagliato nel messaggio.

  2. Il nome del programma, il nome della classe e il nome del metodo in cui si è verificato l'errore, in modo che un programmatore o una persona di supporto possano trovare il codice.

  3. Se possibile, suggerisci le azioni che l'utente può intraprendere per correggere il problema.

Il solo uso dei codici di errore è troppo criptico per un programma facile da usare e non altrettanto facile da decodificare da una persona di supporto come si potrebbe pensare. Inevitabilmente, l'errore si verificherà quando il rappresentante di supporto è lontano dalla sua scrivania (a casa per chiamare) o avrà inserito male la lista dei codici di errore.

Quale messaggio preferiresti risolvere?

"Errore programma! Errore 0x80020018"

o "Errore MyProgramName 0X80020018 nel modulo SendMail, l'indirizzo email non è valido. Verifica che l'indirizzo email inserito sia valido e riprova."

    
risposta data 30.09.2015 - 16:19
fonte
2

Quello che ho notato è che c'è un'enorme disconnessione tra ciò che è necessario per diagnosticare un problema e ciò che si visualizza all'utente. I codici di errore e le eccezioni sono semplicemente punti di partenza che ti suggeriscono cosa potrebbe essere andato storto.

Ad esempio: un errore che dice che il caricamento di un file fallito potrebbe essere dovuto al fatto che la rete era inattiva, scollegata, rifiutata, danneggiata, non è stato possibile creare la directory sul server, il file esisteva già, il file esisteva ed era in sola lettura, la directory è stata protetta contro la scrittura dell'utente, il nome del file caricato è troppo lungo, o anche che la fantasia di array SAN cliente ha impiegato 40 secondi per rispondere e il caricamento della rete è scaduto! (dannazione a EMC e al cliente che ha configurato male l'array di archiviazione!)

Il problema qui è che mentre vuoi dire all'utente "fallito di caricare", non vuoi veramente creare eccezioni o codice di errore per tutte le possibili permutazioni di ciò che potrebbe essere andato storto - in particolare nell'ultimo caso in cui il file sembra essere stato scritto correttamente quando vai a cercare. Ho sempre trovato che un meccanismo di registrazione decente valga il suo peso, quando si verifica un errore che non può essere semplicemente ritentato dall'utente, i registri verranno visualizzati per vedere cosa è successo. I log spesso non ti dicono l'errore esatto, ma dovrebbero fornire sufficienti informazioni di tracciamento (inclusi i codici di errore scritti in essi) per diagnosticare i problemi con i dati o l'ambiente che hanno portato alla condizione di errore.

Per quanto riguarda le eccezioni v codici di errore, preferisco quest'ultimo, anche se vengono lanciati come eccezioni! Se si utilizzano i codici di errore, sarà necessario fornire un meccanismo per convertirli in descrizioni di testo, una serie di codici di errore per modulo (o classe) ha senso evitare la necessità di afferrare un nuovo codice univoco e mantenere i codici di errore da un modulo sequenziale.

    
risposta data 30.09.2015 - 16:45
fonte
0

Dal punto di vista del problema che stai affrontando, un messaggio del tipo "Impossibile creare xyz" non è assolutamente diverso da "Errore di run-time '1004'". Se l'eccezione "Impossibile creare xyz" viene lanciata in una dozzina di punti in tutto il sistema, così può essere emesso un errore "Errore di runtime" 1004 "" in una dozzina di punti in tutto il sistema. Sostituire l'una con l'altra non ti aiuta in alcun modo.

Generalmente, le eccezioni sono sempre in una posizione lontana più utile dei codici di errore.

Hai un certo numero di opzioni.

Se per caso è molto facile raccogliere i file di registro dal campo, è possibile generare un nuovo numero di errore univoco ogni volta che si verifica un errore e archiviarlo nel registro insieme all'eccezione, in modo che sai dove cercare nel file di registro. In questo modo, puoi presentare al tuo utente un messaggio come "ERRORE 2624501; contatta l'assistenza tecnica" ma il numero di errore è sempre diverso, anche se il tipo di errore è lo stesso.

Se la raccolta dei file di registro non è semplice, è necessario disporre di un mezzo per identificare in modo univoco ogni singolo luogo che può generare un'eccezione. Il modo in cui viene tradizionalmente fatto è il numero di rilascio, il nome del file di origine e il numero di riga.

Ogni eccezione che si getta contiene una traccia dello stack e la voce più in alto della traccia dello stack dovrebbe contenere il nome del file e il numero della linea, quindi è possibile segnalarli. (Naturalmente, l'eccezione potrebbe essere stata causata da un'altra eccezione, quindi è necessario prima attraversare dapprima la catena di cause delle eccezioni.)

La versione di rilascio è necessaria perché è probabile che tu stia facendo una release agli utenti e poi continui a lavorare sul tuo codice sorgente, quindi il codice cambia, quindi una particolare riga che genera un'eccezione sulla versione dell'utente finale può non lanciare alcuna eccezione sul codice che hai di fronte, quindi potresti aver bisogno di cercare una versione specifica del file sorgente nel tuo sistema di controllo versione.

Se non si desidera divulgare agli utenti finali informazioni altamente tecniche come i nomi dei file di origine, potrebbe essere necessario offuscarli associando ciascun nome di file di origine a un altro numero e mostrando solo i numeri degli utenti finali.

Potresti persino automatizzare la convalida di questa procedura, in modo da garantire che non ci siano due classi con lo stesso numero. Puoi avere ogni classe che può lanciare un registro di eccezioni con un oggetto "autorità di confondimento centrale", che si assicura che il numero univoco di ogni classe sia davvero unico, quindi se non lo è, si romperà durante una prova e non sul campo.

Sfortunatamente, riportare solo il punto in cui si è verificato l'errore non è molto utile, perché ad esempio potresti avere una funzione centrale che apre tutti i tuoi file, quindi un'eccezione generata da quella funzione non ti dice molto. Quale sottosistema ha provato ad aprire quel file? Per quale scopo? Qual era il nome del file? Ecco perché sono complete le tracce dello stack delle eccezioni.

Il metodo che consiglierei è un po 'complicato, ma è il migliore.

Prendi l'intera traccia dello stack di eccezioni in una stringa, inclusi tutti i messaggi di eccezione e tutte le eccezioni causali, e applica la compressione ZIP per renderla piccola. Quindi, applica la codifica base 64 per ottenere una stringa che può essere copiata e incollata in un'e-mail. Aggiungi una finestra di "ulteriori informazioni" alle finestre di dialogo di errore, che presenta questa strana lunga sequenza di caratteri agli utenti finali, chiedendo loro di inviarcele via email. In questo modo, è possibile invertire la procedura di codifica, (decodifica in base 64, quindi in unZIP) e puoi avere tutte le informazioni pertinenti nelle tue mani.

    
risposta data 30.09.2015 - 17:19
fonte

Leggi altre domande sui tag