Acabei de ver uma pergunta sobre try-catch , que pessoas (incluindo Jon Skeet) dizem que blocos vazios de captura são uma péssima idéia? Porque isso? Não há situação em que uma captura vazia não seja uma decisão de projeto errada?
Quero dizer, por exemplo, às vezes você deseja obter informações adicionais de algum lugar (serviço da web, banco de dados) e realmente não se importa se receberá ou não essas informações. Então você tenta obtê-lo e, se acontecer alguma coisa, tudo bem, vou adicionar um "catch (Exceção ignorada) {}" e isso é tudo
exception-handling
try-catch
Samuel Carrijo
fonte
fonte
Respostas:
Normalmente, try-catch vazio é uma má idéia, porque você está engolindo silenciosamente uma condição de erro e, em seguida, continua a execução. Ocasionalmente, isso pode ser a coisa certa a ser feita, mas geralmente é um sinal de que um desenvolvedor viu uma exceção, não sabia o que fazer e, portanto, usou uma captura vazia para silenciar o problema.
É o equivalente de programação de colocar fita preta sobre uma luz de aviso do motor.
Acredito que a maneira como você lida com exceções depende de qual camada do software você está trabalhando: Exceções na Floresta Tropical .
fonte
Eles são uma péssima idéia em geral, porque é uma condição verdadeiramente rara em que uma falha (condição excepcional, mais genericamente) é atendida adequadamente, sem resposta alguma. Além disso, os
catch
blocos vazios são uma ferramenta comum usada por pessoas que usam o mecanismo de exceções para verificação de erros que deveriam estar executando preventivamente.Dizer que sempre é ruim é falso ... isso é verdade de muito pouco. Pode haver circunstâncias em que você não se importa com o erro ou a presença do erro de alguma forma indica que você não pode fazer nada a respeito (por exemplo, ao gravar um erro anterior em um arquivo de log de texto e você recebe um
IOException
, o que significa que você não pode escrever o novo erro de qualquer maneira).fonte
Eu não esticaria as coisas ao ponto de dizer que quem usa blocos de captura vazios é um mau programador e não sabe o que está fazendo ...
Eu uso blocos de captura vazios, se necessário. Às vezes, o programador da biblioteca que estou consumindo não sabe o que está fazendo e lança exceções, mesmo em situações em que ninguém precisa.
Por exemplo, considere alguma biblioteca de servidores http, eu não me importaria se o servidor lançasse uma exceção porque o cliente foi desconectado e
index.html
não pôde ser enviado.fonte
Existem casos raros em que isso pode ser justificado. No Python, você costuma ver esse tipo de construção:
Portanto, pode ser bom (dependendo do seu aplicativo) fazer:
Em um projeto .NET recente, tive que escrever um código para enumerar DLLs de plug-in para encontrar classes que implementam uma certa interface. O bit de código relevante (no VB.NET, desculpe) é:
Embora, mesmo nesse caso, eu admita que registrar a falha em algum lugar provavelmente seja uma melhoria.
fonte
Blocos de captura vazios geralmente são inseridos porque o codificador realmente não sabe o que está fazendo. Na minha organização, um bloco de captura vazio deve incluir um comentário sobre por que não fazer nada com a exceção é uma boa idéia.
Em uma observação relacionada, a maioria das pessoas não sabe que um bloco try {} pode ser seguido com um catch {} ou finalmente {}, apenas um é necessário.
fonte
Exceções só devem ser lançadas se houver realmente uma exceção - algo acontecendo além da norma. Um bloco vazio de captura basicamente diz "algo ruim está acontecendo, mas eu simplesmente não me importo". Esta é uma má ideia.
Se você não quiser lidar com a exceção, deixe que ela se propague para cima até atingir algum código que possa lidar com ela. Se nada puder lidar com a exceção, o aplicativo deverá ser desativado.
fonte
catch (Exception) {}
seja uma má idéia,catch (SpecificExceptionType) {}
pode estar perfeitamente bem. O programador DID inspecionou a exceção, usando as informações de tipo na cláusula catch.Acho que tudo bem se você pegar um tipo de exceção específico, do qual você sabe que só será levantado por um motivo específico , e espera essa exceção e realmente não precisa fazer nada a respeito.
Mas mesmo nesse caso, uma mensagem de depuração pode estar em ordem.
fonte
Por Josh Bloch - Item 65: Não ignore as exceções do Java eficaz :
fonte
Um bloco de captura vazio está basicamente dizendo "Não quero saber quais erros são lançados, apenas os ignorarei".
É semelhante ao VB6
On Error Resume Next
, exceto que qualquer coisa no bloco try após a exceção ser lançada será ignorada.O que não ajuda quando algo então quebra.
fonte
Isso ocorre em conjunto com "Não use exceções para controlar o fluxo do programa" e "Somente use exceções para circunstâncias excepcionais". Se isso for feito, as exceções só deverão ocorrer quando houver um problema. E se houver algum problema, você não deseja falhar silenciosamente. Nas raras anomalias em que não é necessário lidar com o problema, você deve pelo menos registrar a exceção, caso a anomalia não se torne mais uma anomalia. A única coisa pior do que falhar é falhar silenciosamente.
fonte
Eu acho que um bloco de captura completamente vazio é uma má idéia, porque não há como inferir que ignorar a exceção foi o comportamento pretendido do código. Não é necessariamente ruim engolir uma exceção e retornar falso ou nulo ou algum outro valor em alguns casos. A estrutura .net possui muitos métodos "try" que se comportam dessa maneira. Como regra geral, se você engolir uma exceção, adicione um comentário e uma instrução de log se o aplicativo suportar o log.
fonte
Como se uma exceção for lançada, você nunca a verá - falhar silenciosamente é a pior opção possível - você terá um comportamento incorreto e não fará ideia de onde isso está acontecendo. Pelo menos coloque uma mensagem de log lá! Mesmo que seja algo que 'nunca possa acontecer'!
fonte
Blocos de captura vazios são uma indicação de um programador que não sabe o que fazer com uma exceção. Eles estão suprimindo a exceção de possivelmente borbulhar e serem manipulados corretamente por outro bloco de tentativa. Sempre tente fazer algo com a exceção que você está capturando.
fonte
Acho que o mais irritante com instruções de captura vazias é quando algum outro programador fez isso. O que quero dizer é que quando você precisa depurar o código de outra pessoa, qualquer instrução catch vazia torna essa tarefa mais difícil do que precisa. As instruções catch do IMHO sempre devem mostrar algum tipo de mensagem de erro - mesmo que o erro não seja tratado, ele deve pelo menos detectá-lo (alt. Ativado apenas no modo de depuração)
fonte
Provavelmente nunca é a coisa certa, porque você passa silenciosamente todas as exceções possíveis. Se você está esperando uma exceção específica, deve testá-la e tentar novamente, se não for sua exceção.
fonte
Geralmente, você só deve capturar as exceções que realmente pode tratar. Isso significa ser o mais específico possível ao capturar exceções. Capturar todas as exceções raramente é uma boa idéia e ignorar todas as exceções é quase sempre uma péssima idéia.
Só consigo pensar em alguns casos em que um bloco de captura vazio tem algum objetivo significativo. Se qualquer exceção específica que você estiver capturando for "manipulada", apenas tentando novamente a ação, não haverá necessidade de fazer nada no bloco catch. No entanto, ainda seria uma boa idéia registrar o fato de que a exceção ocorreu.
Outro exemplo: o CLR 2.0 mudou a maneira como as exceções não tratadas no thread do finalizador são tratadas. Antes da versão 2.0, o processo podia sobreviver a esse cenário. No CLR atual, o processo é encerrado no caso de uma exceção não tratada no encadeamento do finalizador.
Lembre-se de que você só deve implementar um finalizador se realmente precisar de um e, mesmo assim, deve fazer o mínimo possível no finalizador. Mas se o trabalho que seu finalizador deve executar pode gerar uma exceção, você precisa escolher entre o menor dos dois males. Deseja encerrar o aplicativo devido à exceção não tratada? Ou você deseja prosseguir em um estado mais ou menos indefinido? Pelo menos em teoria, o último pode ser o menor de dois males em alguns casos. Nesses casos, o bloco de captura vazio impediria o término do processo.
fonte
Então, seguindo o seu exemplo, é uma má ideia nesse caso, porque você está capturando e ignorando todas as exceções. Se você estivesse pegando apenas
EInfoFromIrrelevantSourceNotAvailable
e ignorando, tudo bem, mas você não está. Você também está ignorandoENetworkIsDown
, o que pode ou não ser importante. Você está ignorandoENetworkCardHasMelted
eEFPUHasDecidedThatOnePlusOneIsSeventeen
, que são quase certamente importantes.Um bloco de captura vazio não é um problema se estiver configurado para capturar (e ignorar) exceções de certos tipos que você sabe que não são importantes. As situações em que é uma boa idéia suprimir e ignorar silenciosamente todas as exceções, sem parar para examiná-las primeiro e verificar se são esperadas / normais / irrelevantes ou não, são extremamente raras.
fonte
Há situações em que você pode usá-las, mas elas devem ser muito raras. As situações em que eu poderia usar um incluem:
registro de exceção; dependendo do contexto, você pode querer publicar uma exceção não tratada ou uma mensagem.
situações técnicas em loop, como renderização ou processamento de som ou um retorno de chamada da caixa de listagem, em que o próprio comportamento demonstrará o problema, lançar uma exceção apenas atrapalhará e o registro da exceção provavelmente resultará em milhares de mensagens "com falha no XXX" .
programas que não podem falhar, embora ainda devam ao menos registrar alguma coisa.
para a maioria dos aplicativos winforms, descobri que basta ter uma única instrução try para cada entrada do usuário. Eu uso os seguintes métodos: (AlertBox é apenas um invólucro rápido MessageBox.Show)
Então, todo manipulador de eventos pode fazer algo como:
ou
Teoricamente, você pode ter o TryActionSilently, que pode ser melhor para renderizar chamadas, para que uma exceção não gere uma quantidade infinita de mensagens.
fonte
Se você não sabe o que fazer no bloco catch, basta registrar essa exceção, mas não a deixe em branco.
fonte
Você nunca deve ter um bloco de captura vazio. É como esconder um erro que você conhece. No mínimo, você deve escrever uma exceção em um arquivo de log para revisar mais tarde, se você pressionar o tempo.
fonte