L'errore sta sopprimendo le cattive pratiche?


14

Su una domanda SO che ho fatto qui su un codice di cui non ero sicuro, qualcuno ha risposto "BTW, codice orribile lì: usa molto il simbolo di soppressione dell'errore (@)".

C'è un motivo per cui questa è una cattiva pratica? Con cose come:

$db=@new mysqli($db_info) or die('Database error');

, mi consente di visualizzare solo un messaggio di errore personalizzato. Senza la soppressione degli errori, visualizzerebbe comunque il tipico messaggio PHP di:

Avvertenza : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo non riuscito: non è noto tale host. in alcuni \ file \ path alla riga 6

così come "Errore del database".

La soppressione degli errori è sempre negativa e, in caso affermativo, che cosa è specificamente negativo di quanto sopra?

Aggiornamento: il codice effettivo che sto usando è:

or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b><br />Error occurred on line <b>' . __LINE__ . '</b> of <b>' . __FILE__ . '</b>' : ''))

che rimuove tutto l'output precedente e visualizza un messaggio di errore. Quindi il fatto che il messaggio di errore non includa dettagli su ciò che è specificamente accaduto (che la gente sembra suggerire come un motivo per cui la soppressione degli errori è male) è irrilevante.


9
Indossa una benda mentre stai guidando cattive pratiche?
Damien Roche,

Come può essere una domanda seria? Immagino che se ti piace scrivere codice che impiega ore per eseguire il debug, la soppressione degli errori sarebbe una buona cosa. Pensaci, la tua app fallisce, corrompe i dati ... e non vuoi sapere perché o dove nel codice. Quando sarebbe mai una buona idea? Devi invitare i tuoi amici a fare una festa su di te ... segue la stessa logica.
Qualche muratore gratuito il

1
@SomeFreeMason Se dovessi eseguire il debug, impostare $ debug_mode su TRUE, poiché il codice effettivo che sto usando è:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))

@Paradoxical: mi rendo conto che lo stato dell'eccezione / gestione degli errori in PHP è un po 'FUBAR, ma sei consapevole che puoi disattivare la visualizzazione visiva degli errori nella tua configurazione PHP, giusto?
Phoshi,

@Phoshi sfortunatamente il servizio di hosting che sto usando non mi dà accesso a php.ini

Risposte:


14

Penso che tu stia facendo la cosa giusta sopprimendo l'errore, perché stai implementando la tua gestione degli errori.

Potrebbe essere più semplice considerare l'equivalente, ad esempio, in Java. Sopprimere l'errore utilizzando @è analogo a ingoiare un'eccezione. Il seguente codice, simile al tuo, è ragionevole:

try {
    db = new MySQLi(dbInfo);
} catch (SQLException connectionFailure) {
    die("Database error");
}

(Beh, in Java, non vorrai che il motore servlet muoia, ma ti viene l'idea.)

Tuttavia, questo non è accettabile:

try {
    db = new MySQLi(dbInfo);
} catch (Exception e) {
}

La maggior parte della soppressione degli errori PHP viene eseguita con noncuranza, analogamente a quest'ultimo esempio, da cui la reazione istintiva contro il codice.


3
Non chiamerei catturare l'eccezione e fermare l'esecuzione per "gestirla". Se riesci a risolvere il problema, ottimo, fallo. Se non puoi, che diavolo stai facendo per prenderlo? Questo è ciò per cui abbiamo gestori di eccezioni di livello superiore. La cattura delle eccezioni in questo caso sta solo assicurandosi di avere un errore nella gestione del codice sparso su tutta la base di codice.
Phoshi,

7

La soppressione degli errori è negativa, perché non nasconde solo le informazioni che già conosci ( qualcosa è andato storto). Potrebbe anche nascondere informazioni vitali per il debug di cui non sei a conoscenza ( cosa , dove e perché ).

In questo esempio specifico, " Errore database " non è un ottimo messaggio di errore. Qualcosa è andato storto nel DB. Non molto illuminante. L' avvertimento: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo non è riuscito: non si conosce tale host. in alcuni \ file \ path sulla riga 6 "è in realtà un messaggio di errore migliore. Ti dà una posizione e un motivo per il problema. Puoi saltare subito e iniziare il debug, perché l'errore è già stato individuato.

Naturalmente, i progettisti di biblioteche a volte hanno la tendenza a far apparire molti avvertimenti irrilevanti. Non conosco PHP sufficientemente bene per sapere se ha un modo per filtrare gli avvisi che non ti interessano. So che leggere attraverso uno stack stack di cento righe non è molto illuminante. Ma la risposta corretta a troppe informazioni non è quella di ridurre la quantità di informazioni a zero , ma di filtrare le parti irrilevanti a un certo punto. L' @operatore non ha questa granularità (il suo motto è tutto o niente ) e non è quindi uno strumento adatto per un'efficace gestione degli errori.

Ci sono alcuni casi in cui sai che si verificherà un certo errore e che risolvere il problema reale è più costoso che mettere a tacere il messaggio (e subire potenziali ricadute da quello). Questo potrebbe essere il caso di uno script unico, ma infilare le dita nelle orecchie e andare " la la la " non è una risposta professionale a (potenziali) bug.


5
Non vuoi dire ai tuoi utenti l'errore esatto. Li informi che l'errore è dalla tua parte e che ci stai lavorando. Puoi registrare gli errori sul tuo server e impostare avvisi in modo da conoscerli automaticamente, ma non c'è motivo di mostrare questi errori all'utente.
Jeroen Vannevel,

1
Su un sito live, sarebbe sicuramente meglio per un messaggio di errore che l'utente tipico può capire di essere visualizzato, piuttosto che "un po 'di spazzatura tecnica su un mysqli, qualunque cosa sia", però? Se sto provando a eseguire il debug, rimuoverei la soppressione dell'errore, ma in un sito live non sono d'accordo sul fatto che l'errore completo dovrebbe essere visualizzato.

3
@Paradoxical Su un sito serio, non visualizzerai un messaggio di errore come "errore del database" e nient'altro. Visualizzeresti una pagina generica di "errore interno del server" con un sacco di lanugine, stile, piè di pagina, ecc. Che dienon è adatto neanche per. E le informazioni dettagliate dovrebbero andare in un registro indipendentemente da ciò che mostri all'utente .

1
Non è possibile presentare un messaggio intuitivo sullo schermo e scrivere il messaggio tecnico in un file di registro?
FrustratedWithFormsDesigner,

3
display_errorsoff, log_errorson, e sei praticamente bravo ad andare, fai come ti pare per rilevare un errore, ma non buttarli via.
Wrikken,

0

Sopprimere gli errori è negativo perché nasconde il problema, di cui molte volte non siamo nemmeno a conoscenza e può comportare comportamenti imprevisti che possono rivelarsi molto costosi in alcune applicazioni critiche, ad esempio in applicazioni utilizzate in settori finanziari, sanitari e di difesa.

Inoltre, non è una buona idea avere eccezioni non gestite nel codice e mostrare i messaggi di errore effettivi all'utente in quanto ciò potrebbe causare problemi di sicurezza perché i messaggi di errore di solito rivelano molto sul codice, il che può aiutare gli utenti malintenzionati e gli hacker a manipolare il sistema.

Quindi la buona pratica è quella di gestire gli errori a diversi livelli, ad esempio al massimo livello, è possibile gestire l'errore semplicemente accedendo all'errore reale e mostrando all'utente un messaggio semplice e intuitivo.


0

Sì, l'errore di soppressione dell'operatore è generalmente una cattiva idea.

È necessario gestire la segnalazione degli errori nella configurazione ( php.ini). Quindi puoi scegliere un'impostazione diversa per ogni ambiente (ad es. Lasciare avvisi in fase di sviluppo e nasconderli in produzione).

L'unica situazione durante l'utilizzo @potrebbe avere senso quando si sviluppa una libreria per altri sviluppatori. Se scegli volontariamente di fare qualcosa che genera un avviso e non vuoi infastidire gli utenti della tua biblioteca con un avviso che non dipende da loro, @potrebbe essere una soluzione.

Non riesco a pensare a nessun altro uso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.