O erro está suprimindo as más práticas?


14

Em uma pergunta SO, perguntei aqui sobre algum código que eu não tinha certeza, alguém respondeu: "Aliás, código horrível lá: ele usa muito o símbolo de supressão de erro (@)".

Existe uma razão para isso ser uma má prática? Com coisas como:

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

, ele permite exibir apenas uma mensagem de erro personalizada. Sem suprimir erros, ele ainda exibirá a mensagem PHP típica de:

Aviso : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo falhou: Nenhum host desse tipo é conhecido. em algum \ arquivo \ caminho na linha 6

bem como 'Erro no banco de dados'.

A supressão de erros é sempre ruim e, em caso afirmativo, o que especificamente está exposto acima é ruim?

Atualização: o código real que estou 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>' : ''))

que remove toda a saída anterior e exibe uma mensagem de erro. Portanto, o fato de a mensagem de erro não incluir detalhes sobre o que aconteceu especificamente (que as pessoas parecem sugerir como uma razão para a supressão de erros ser ruim) é irrelevante.


9
Usar os olhos vendados enquanto você pratica más práticas?
23413 Damien Roche

Como isso poderia ser uma pergunta séria? Eu acho que se você gosta de escrever código que leva horas para depurar, a supressão de erros seria uma coisa boa. Pense nisso: seu aplicativo falha, corrompe os dados ... e você não quer saber por que ou onde no código. Quando isso seria uma boa ideia? Você deve convidar seus amigos para fazer uma festa com você ... segue a mesma lógica.
Some Free Mason

1
@SomeFreeMason Se eu necessidade de depurar então eu só iria definir $ debug_mode para TRUE, uma vez que o código real que estou usando é:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))

@Paradoxical: Eu sei que o estado de exceção / tratamento de erros no PHP é um pouco FUBAR, mas você está ciente de que pode desativar a exibição visual de erros em sua configuração do PHP, certo?
Phoshi #

@Phoshi infelizmente o serviço de hospedagem que estou usando não dá-me acesso a php.ini

Respostas:


14

Acho que você está fazendo a coisa certa suprimindo o erro, porque está implementando seu próprio tratamento de erros.

Pode ser mais fácil considerar o equivalente em, digamos, Java. Suprimir o erro usando @é análogo a engolir uma exceção. O código a seguir, semelhante ao seu, é razoável:

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

(Bem, em Java, você não gostaria que o mecanismo de servlet morresse, mas você entendeu.)

No entanto, isso não é aceitável:

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

A maior parte da supressão de erros do PHP é feita de forma descuidada, análoga ao último exemplo, portanto, a reação instintiva contra o seu código.


3
Eu não chamaria de pegar a exceção e apenas parar a execução para "manipulá-la". Se você puder resolver o problema, ótimo, faça-o. Se você não pode, o que diabos você está fazendo pegando? É para isso que temos os manipuladores de exceção de nível superior. Capturar exceções nesse caso é apenas garantir que você tenha um código de manipulação de erros espalhado por toda a sua base de código.
Phoshi #

7

A supressão de erros é ruim, porque não oculta apenas as informações que você já conhece ( algo deu errado). Também pode ocultar informações vitais para a depuração das quais você não está ciente (o que , onde e por que ).

Neste exemplo específico, " Erro no banco de dados " não é uma mensagem de erro muito boa. Algo deu errado com o DB. Não é muito esclarecedor. O “ Aviso: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo falhou: Nenhum host é conhecido. em alguns \ arquivo \ caminho na linha 6 ”é realmente uma mensagem de erro melhor. Fornece uma localização e uma razão para o problema. Você pode entrar diretamente e iniciar a depuração, porque o erro já foi localizado.

Obviamente, os projetistas de bibliotecas às vezes tendem a trazer muitos avisos irrelevantes. Não sei o PHP suficientemente bem para saber se existe uma maneira de filtrar avisos nos quais você não está interessado. Sei que ler um rastreamento de pilha de cem linhas não é muito esclarecedor. Mas a resposta correta a muitas informações não é reduzir a quantidade de informações a zero , mas filtrar partes irrelevantes em algum estágio. O @operador não possui essa granularidade (seu lema é tudo ou nada ) e, portanto, não é uma ferramenta adequada para o gerenciamento eficaz de erros.

Há alguns casos em que você sabe que um determinado erro será exibido e que corrigir o problema real é mais caro do que silenciar a mensagem (e sofrer possíveis consequências disso). Este poderia ser o caso em um script one-off, mas furar os dedos em seus ouvidos e vai “ la la la ” é não uma resposta profissional a (potenciais) bugs.


5
Você não deseja informar aos usuários o erro exato. Você os informa que o erro está do seu lado e que você está trabalhando nisso. Você pode registrar os erros no servidor e configurar alertas para saber automaticamente, mas não há motivo para mostrar esses erros ao usuário.
Jeroen Vannevel

1
Em um site ao vivo, certamente seria melhor para uma mensagem de erro que o usuário comum possa entender ser exibida, em vez de "algum lixo técnico sobre um mysqli, seja o que for"? Se estou tentando depurá-lo, removo a supressão de erro, mas em um site ativo, discordo que o erro completo deve ser exibido.

3
@Paradoxical Em um site sério, você não exibia uma mensagem de erro como "erro no banco de dados" e nada mais. Você exibia uma página genérica de "erro interno do servidor" com muitos fluff, estilo, rodapé etc., que dietambém não são adequados. E as informações detalhadas devem entrar em um log, independentemente do que você mostrar ao usuário .

1
Não há como apresentar uma mensagem amigável na tela e gravar a mensagem técnica em um arquivo de log?
FrustratedWithFormsDesigner

3
display_errorsoff, log_errorson, e você está pronto para fazer o que quiser, detectando um erro, mas não jogue-o fora.
Wrikken

0

A supressão de erros é ruim porque oculta o problema, do qual muitas vezes nem estamos cientes, e pode resultar em um comportamento inesperado que pode ser muito caro em algumas aplicações críticas, por exemplo, nas aplicações usadas nos domínios financeiro, de saúde e de defesa.

Também não é uma boa idéia ter exceções sem tratamento no código e mostrar as mensagens de erro reais ao usuário, pois isso pode resultar em problemas de segurança, porque as mensagens de erro geralmente revelam muito sobre seu código, o que pode ajudar usuários e hackers mal-intencionados a manipular o sistema.

Portanto, a boa prática é lidar com os erros em diferentes níveis, por exemplo, no nível mais alto, você pode lidar com o erro apenas registrando o erro real e mostrando uma mensagem simples e amigável para o usuário.


0

Sim, o operador de supressão de erros geralmente é uma má ideia.

Você deve gerenciar o relatório de erros na configuração ( php.ini). Assim, você pode escolher uma configuração diferente para cada ambiente (por exemplo, deixe avisos em desenvolvimento e oculte-os em produção).

A única situação em que o uso @pode fazer sentido é quando você desenvolve uma biblioteca para outros desenvolvedores. Se você voluntariamente optar por fazer algo que produza um aviso e não quiser incomodar os usuários da sua biblioteca com um aviso que não dependa deles, @pode ser uma solução.

Não consigo pensar em outro uso.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.