Manipulação de exceção

votos
2

É Manipulação Estruturada de Exceções ruim? O que é a maneira correta de lidar com exceções?

EDIT: Tratamento de exceção no .NET usando C #.

Eu costumo ter um conjunto de classes de exceção específicos (DivideByZeroException, ArrayTypeMismatchException) e não têm um genérico catch (Exception ex).

O pensamento por trás disso é que espero que certos tipos de excepções para ocorrer e têm acções específicas definidas quando eles ocorrem e as exceções inesperadas se levantaria as a interface (Windows ou web). Será esta uma boa prática?

Publicado 09/12/2008 em 15:31
fonte usuário
Em outras línguas...                            


5 respostas

votos
6

Eu não tenho certeza do que você quer dizer com "manipulação de exceção estruturada.

A pior coisa que pode ser feito no tratamento de exceção é 'engolir' a exceção ou manipulá-lo em silêncio.

Não faça isso:

try {
   ...
}
catch (Exception e) {
   //TODO: handle this later
}

Isso é muitas vezes feito por preguiça para obter o código para compilar. Se você não sabe como lidar com a exceção em um nível particular, tem o método de lançar a exceção e ter pelo menos uma captura tudo manipulador no topo. Fornecer feedback de alguma forma (através do GUI, uma página / e-mail para uma pessoa de apoio, arquivo de log) para que o problema pode, eventualmente, ficar fixo. Silenciosamente pegar uma exceção quase sempre leva a um problema maior a acontecer mais tarde, e que seja difícil de rastrear.

Respondeu 09/12/2008 em 15:39
fonte usuário

votos
3

declarações de capturas + rastreamentos de pilha. Nunca capturar uma exceção sem imprimir um rastreamento de pilha, você ou alguém vai ter de checkout que o código novamente e rastreamentos de pilha lugar no bloco Catch quando ocorre um erro e seus arquivos de log são vazio ou vago.

Respondeu 09/12/2008 em 15:33
fonte usuário

votos
1

Este é um tema complexo ... há livros sobre este ... mas ... Existem dois tipos principais de tratamento de exceção ... em linha, onde o código para lidar com possíveis erros está em linha com o código que um método ou de rotina que "normalmente" executar e manipulação de exceção estruturada, onde o código está em outro lugar, e teh infra-estrutura é projetada para switych automaticamente para que o código de manipulação de exceção quando um evento inesperado (um erro) ocorre ... Ambos têm advantedges e disadvanteges. A abordagem "inline" tende a produzir um código que é muito mais desordenado (com código de erro) e mais difícil de ler e manter. Mas é mais fácil de produzir na frente, uma vez que não requer qualquer análise inicial, quando se utiliza o tratamento de erros em linha, você vê muitas vezes os métodos que retornam códigos "erro" boolean ou numéricos, indiocating para o chamador se o metjhod ou rotina foi bem sucedida. Isso elimina a sintaxe "funcional" de ter um "retorno" de rotina um valor de negócio significativo ou objeto, (uma vez que cada função por convenção deve retornar um código de erro) Ao usar o tratamento de exceção estruturada, esta questão é discutível.

Manipulação de exceção estruturada, otoh, em geral, é mais difícil de fazer bem, pois requer-se a análise da frente, como o que erros uma rotina ou método poderia produzir, e quanto ao que o método pode ou deve fazer sobre cada erro se ele ocorrer.

Uma coisa é certa, não misturar as duas abordagens em um único componente ...

Respondeu 09/12/2008 em 15:59
fonte usuário

votos
1

Minha recomendação:

Não capturar uma exceção a menos que:

  • Não fazer isso poderia causar falhas no aplicativo (por exemplo, um manipulador de eventos)
    • E nesta situação, certifique-se de registrar a exceção para que você sabe o que aconteceu e quando
  • Você pode fazer alguma coisa para tentar remediar a situação (por exemplo, a implementação de um mecanismo de repetição ao chamar uma API externa que ocasionalmente gera uma exceção (note que o tratamento de exceção não deve ser usado para controlar o fluxo do programa))
    • E nesta situação, apenas a pegar o tipo de exceção específica que você espera são jogados

Captura a exceção ao mais alto nível possível significa que você começa a pilha máximo de chamada, que é muito útil quando você está passando os logs e tentar ver o que ação inicial desencadeou a sequência de eventos que levou à exceção em primeiro lugar .

Respondeu 09/12/2008 em 15:45
fonte usuário

votos
0

Eu não sou um programador Windows, mas parece-me que o uso de manipulação de exceção estruturada para tratar exceções de hardware como de software exceções significa que:

  • Seu código faz algo que no C ++ padrão produz um comportamento indefinido ou definido pela implementação (tais como divisão por zero).
  • O Windows define que, com SEH habilitado ele lança uma exceção nesse caso.
  • Você está usando esse fato para capturar a exceção e / ou executar um manipulador de conclusão.

Assim, as perguntas a serem feitas, IMO, são:

  • É a sua tarefa de programação realmente de uma natureza que padrão C ++ não consegue lidar? (Ou só pode tratar de uma forma que é mensurável inferior ao que você recebe, permitindo a exceção de hardware).
  • Você realmente precisa de tomar medidas quando o código vai não-padrão?
  • você pode escrever seu código para que ele não provoca exceções de hardware em primeiro lugar?

Se as respostas são 'sim', 'sim', 'não', é necessária a manipulação de exceção, em seguida, estruturada. Caso contrário, você pode ser capaz de evitá-lo, caso em que você provavelmente vai querer. Escrevendo código de exceção-safe é complicado, por isso quanto mais forte a exceção garante que você pode oferecer o melhor. Código que talvez divide por zero com SEH não está oferecendo a garantia nothrow, quando talvez com um pouco de redesenho para que os chamadores não dar-lhe dados Duff, ele poderia fazê-lo. Mas se uma função já tem que lançar exceções por outras razões, em seguida, também possivelmente jogá-los para armadilhas de hardware pode tornar as coisas não pior.

Um caso especial notável é a alocação de memória. Não tenho certeza se o .NET faz isso, mas na alocação linux só não se há suficiente espaço de endereço virtual para a alocação. Memória física está comprometida na primeira utilização, e faz com que uma exceção de hardware se não é suficiente. Desde alocação de memória é suposto para jogar std :: bad_alloc em caso de falha, ea implementação falha em implementar este requisito da norma, que podeser que, em alguns casos convertendo a exceção de hardware para software é a coisa certa a fazer. No entanto, essa exceção hardware pode ocorrer em lugares inesperados, (incluindo em rotinas que você achava que eram nothrow), por isso ainda pode ser impossível lidar com graciosamente, razão pela qual núcleo linux despeja em vez de jogar. Na prática, qualquer coisa que começa inicializado completamente irá travar seu construtor, que muitas vezes é perto o suficiente para a alocação que uma exceção de software em vez seria útil.

Respondeu 09/12/2008 em 16:06
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more