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.
fonte
or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))
Respostas:
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:(Bem, em Java, você não gostaria que o mecanismo de servlet morresse, mas você entendeu.)
No entanto, isso não é aceitável:
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.
fonte
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.
fonte
die
também não são adequados. E as informações detalhadas devem entrar em um log, independentemente do que você mostrar ao usuário .display_errors
off,log_errors
on, e você está pronto para fazer o que quiser, detectando um erro, mas não jogue-o fora.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.
fonte
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.
fonte