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.