Come posso migliorare il controllo e la gestione degli errori?

13

Ultimamente ho faticato a capire qual è la giusta quantità di controllo e quali sono i metodi corretti.

Ho alcune domande a riguardo:

Qual è il modo corretto per verificare la presenza di errori (input errati, stati non validi, ecc.)? È meglio controllare esplicitamente gli errori o utilizzare funzioni come assert che possono essere ottimizzate dal tuo codice finale? Mi sento di controllare esplicitamente un programma con un sacco di codice in più che non dovrebbe essere eseguito nella maggior parte delle situazioni - e per non parlare della maggior parte degli errori si finisce con un fallimento di interruzione / uscita. Perché ingombrare una funzione con controlli espliciti solo per abortire? Ho cercato affermazioni rispetto al controllo esplicito degli errori e ho trovato poco per spiegare veramente quando fare entrambi.

La maggior parte dice "usa asserti per verificare gli errori logici e usa controlli espliciti per verificare altri errori". Questo non sembra farci molto lontano però. Diremmo che questo è fattibile:

Malloc returning null, check explictly
API user inserting odd input for functions, use asserts

Questo mi renderebbe migliore nel controllo degli errori? Cos'altro posso fare? Voglio davvero migliorare e scrivere meglio, codice 'professionale'.

    
posta Corey Prophitt 27.10.2011 - 17:50
fonte

5 risposte

4

Il modo più semplice per me di distinguere è determinare se la condizione di errore viene introdotta in fase di compilazione o in fase di esecuzione. Se il problema è un programmatore che usa la funzione in qualche modo sbagliata, falla notare per attirare l'attenzione sul problema, ma una volta che la correzione è stata compilata nel codice chiamante, non devi più preoccuparti di controllarla. Problemi come l'esaurimento della memoria o il cattivo input dell'utente finale non possono essere risolti al momento della compilazione, quindi lascia i controlli.

    
risposta data 27.10.2011 - 19:58
fonte
2

Controlla qualsiasi cosa in qualsiasi momento (potrebbe essere cambiata dopo l'ultimo controllo) che non è al 100% sotto il comando tuo . E anche: durante lo sviluppo anche non fidarti di te stesso! ; -)

Okokok ... "qualsiasi cosa" è inteso per essere letto come controllo di cose che potrebbero causare una anormale interruzione o qualsiasi cosa che possa far sì che la tua applicazione / sistema faccia cose che dovrebbe non fai.

Per essere seri, l'ultima parte dell'ultima frase è essenziale perché punta al problema principale:

Se vuoi costruire un sistema stabile, il problema principale non riguarda ciò che il sistema dovrebbe fare, ma lasciare che sia in grado di fare tali cose obbligatorie, bisogna occuparsi di ciò che dovrebbe non em> do, anche se "ingombra il tuo codice".

    
risposta data 27.10.2011 - 19:01
fonte
2

Il punto cruciale della gestione degli errori non è se e come si prende il problema. È più di che cosa fai dopo averlo imparato a riguardo .

Prima di tutto - direi, non c'è motivo per cui ogni singolo errore restituito dal metodo subordinato restituisca non dovrebbe essere gestito. E gli errori e le eccezioni sono solo più dei valori di ritorno o di tutti i try / catch.

  1. Il lancio e la cattura non bastano.
    Vedi questo : dove l'autore lo spiega semplicemente prendendo ma senza fare nulla potenzialmente sopprime l'eccezione e a meno che non sia fatto a sufficienza annullare il danno - è peggio che lasciare che il codice vada come quello. Allo stesso modo basta scrivere "log" quando c'è un file aprire o leggere l'errore potrebbe aiutare a trovare il motivo per cui - ma per il momento il programma termina, potrebbe aver causato danni ai dati! esso non è abbastanza per dire che ho molti try / catch - è più importante per sapere cosa fanno veramente!

  2. Non abusare del try and catch.
    Alcune volte - per lo più programmatori pigri o ingenui pensate che dopo aver scritto un numero sufficiente di tentativi, il loro lavoro è finito e facile. Molto spesso è meglio applicare azioni correttive e riprendere piuttosto che scaricare l'intera faccenda. Se questo non può essere fatto, è necessario decidere a quale livello è necessario tornare indietro. A seconda del contesto e della gravità, prova a catturare le esigenze di nidificazione richiede un'attenta progettazione. Per esempio- Vedi questo e questo

  3. Definire chi è responsabile:
    Una delle prime cose da fare è definire se l'input dato alla routine stessa è solo uno scenario inaccettabile (o non gestito fino ad ora) o è l'eccezione dovuta all'ambiente (come problemi di sistema, problemi di memoria), o questa situazione è una conseguenza completamente interna del risultato dell'algoritmo. In tutti i casi, il livello a cui si desidera tornare o l'azione che si desidera eseguire varia in modo significativo. In questa luce vorrei dire - che quando si esegue il codice in produzione - fare abort () per uscire dal programma è buono - ma non per ogni piccola cosa. Se rilevi la corruzione della memoria o la memoria è chiaro che anche dopo aver fatto del tuo meglio, le cose moriranno. Ma se si riceve un puntatore NULL all'ingresso - non andrei a chiamare abort () -i preferisco rispedirlo al chiamante con un errore e vedere se è abbastanza intelligente da capire se può correggersi.

  4. Definisci qual è il miglior risultato possibile:
    Ciò che tutte le cose devono essere fatte sotto l'eccezione è molto critico. Per esempio se in uno dei nostri casi - un lettore multimediale scopre che non ha dati completi da riprodurre all'utente - cosa dovrebbe fare?

    • salta qualche parte brutta e vedi se può andare avanti bene cose.
    • se questo accade troppo, considera se può saltare al prossimo canzone.
    • se trova che non è in grado di leggere alcun file - stop e mostra qualcosa.
    • nel frattempo
    • in base a quale stato dovrebbe essere un giocatore POP-UP per l'utente e
    • quando dovrebbe portare avanti da solo?
    • Dovrebbe "fermare" le cose per chiedere al feed dell'utente
    • o dovrebbe mettere una piccola nota di errore non invadente in qualche angolo?

    Tutte queste sono soggettive - e forse ci sono più modi per gestire i problemi di quanto non si possa dire. Tutto quanto sopra richiede di costruire e comprendere la profondità dell'eccezione e di rendere possibili diversi scenari in cui evolvere.

  5. A volte dobbiamo controllare le eccezioni prima che si presentino. Il l'esempio più comune è l'errore di divisione per zero. Idealmente si deve prova che prima viene lanciata tale eccezione - e se questo è il caso- prova a mettere il valore non-zero più appropriato e vai avanti piuttosto che suicidarsi!

  6. Pulizia. Almeno questo è quello che devi fare! Se si verifica una funzione aprire 3 file e il quarto non riesce ad aprire - inutile dire il i primi 3 avrebbero dovuto essere chiusi. Delegare questo lavoro a un livello sopra è una cattiva idea. se decidi di non andartene senza pulizia della memoria. E la cosa più importante - anche se sei sopravvissuto al eccezione, informate più in alto che le cose non hanno preso il corso normale.

Il modo in cui vediamo la funzionalità (normale) del software in termini di varie gerarchie o livelli o astrazioni, allo stesso modo dobbiamo classificare le eccezioni in base alla gravità e l'ambito in cui si verificano e influenzano altre parti del sistema - che definisce come gestire eccezioni così diverse nel miglior modo possibile.

Miglior riferimento: Code Craft capitolo 6 - disponibile per scaricare

    
risposta data 27.10.2011 - 22:18
fonte
1

Il controllo degli errori durante le compilazioni di debug è solo BAD IDEA (tm), compila sotto sovrapposizioni di rilasci variabili riutilizzabili sullo stack, rimuove le pagine di guardia, fa trucchi con i calcoli, sostituisce artritici pesanti con turni precalcolati e così via.

Usa il controllo degli errori anche nel rilascio, puoi ricorrere a qualcosa di semplice come:

if(somethinghitthefan)
     abort();

Questo ha anche un ottimo effetto collaterale che sicuramente non ignorerai il bug una volta che l'applicazione si è arrestata in modo anomalo sul PC di betta tester.

I registri e i registri degli eventi sono completamente inutili rispetto a abort() , che li controlla comunque?

    
risposta data 27.10.2011 - 21:06
fonte
0

Le varie cose che puoi fare è
 1. Leggere e assimilare molto codice online e vedere come è fatto  2.Utilizzare alcuni strumenti di debug in modo da aiutare a individuare le regioni di errori
3. Essere consapevoli di errori banali dovuti a assegnazioni improprie e errori di sintassi. Pagina 4. Alcuni errori peggiori arrecano a causa di errori logici nel programma che sono più difficili da trovare. Per questo è possibile estenderlo e trovare o per quelli più complicati provare a parlare con le persone o utilizzare risorse come Stackoverflow , Wikipedia , google per ottenere aiuto dalle persone.

    
risposta data 18.11.2011 - 19:07
fonte

Leggi altre domande sui tag