Como você ensina o tratamento de exceções para programadores? Todas as outras coisas são ensinadas facilmente - Estruturas de Dados, ASP.NET, WinForms, WPF, WCF - você escolhe, tudo pode ser ensinado facilmente.
Com o tratamento de exceções, ensiná-los try-catch-finalmente é apenas a natureza sintática do tratamento de exceções.
O que deve ser ensinado, no entanto, é - Qual parte do seu código você coloca no bloco try ? O que você faz no bloco catch ?
Deixe-me ilustrar com um exemplo.
Você está trabalhando em um projeto Windows Forms (um pequeno utilitário) e o criou como abaixo com 3 projetos diferentes.
- UILayer
- BusinessLayer
- DataLayer
Se uma exceção (digamos que o carregamento de um XDocument lança uma exceção) é gerada no DataLayer (o UILayer chama BusinessLayer que, por sua vez, chama DataLayer), faça o seguinte
//In DataLayer
try {
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(Exception ex)
{
throw ex;
}
que é lançado novamente no BusinessLayer e que é capturado no UILayer onde eu o gravo no arquivo de log?
É assim que você lida com o Exception Handling?
Respostas:
Para explicar o tratamento de exceções, explique o conceito por trás dele: O código em que ocorre um erro freqüentemente não sabe como lidar adequadamente com esse erro. O código que sabe como manipulá-lo corretamente pode ser a função que chamou esse, ou pode estar mais acima na pilha de chamadas.
Ao escrever uma rotina que chama uma rotina que pode gerar uma exceção, se você souber como lidar com esse erro corretamente, coloque a chamada em um bloco try e coloque o código de tratamento de erros no bloco catch. Caso contrário, deixe em paz e deixe que algo acima de você na pilha de chamadas lide com o erro.
Dizer "catch ex, throw ex" não é uma boa maneira de lidar com exceções, pois na verdade não lida com nada. Além disso, dependendo de como o modelo de exceção no seu idioma funciona, isso pode ser realmente prejudicial se limpar as informações de rastreamento de pilha que você poderia ter usado para depurar o problema. Apenas deixe a exceção propagar a pilha de chamadas até atingir uma rotina que saiba como lidar com isso.
fonte
Como a maioria das coisas, as exceções e o tratamento de exceções provavelmente parecerão uma solução em busca de um problema para os novos programadores, até que você mostre por que a solução aparentemente mais simples (códigos de retorno no estilo C e errno) funciona tão mal. Eu começaria motivando o problema e colocando-o em contexto. Mostre como o tratamento de erros pode ser feito usando códigos de retorno ou variáveis globais / estáticas. Em seguida, dê exemplos de por que não funciona bem. Então, e somente então, introduza exceções e explique que elas são uma forma de sinalização fora da banda e que o ponto principal é que o comportamento padrão, se você ignorar uma exceção, é passar o dinheiro da pilha de chamadas para alguém que possa lidar com isso.
Conclusão: mostrar como o tratamento de erros foi feito em C fará com que os alunos entendam para que servem realmente as exceções e por que capturar exceções que você realmente não consegue lidar é basicamente simular a maneira como as coisas foram feitas na Idade das Trevas.
fonte
Eu começaria com as diretrizes de design para exceções, que são curtas e inclui DO, DO NOT e EVOID. Também fornece os motivos.
No seu caso de exemplo, a seção revelvent seria Wrapping Exceptions
E esperaria que fosse escrito dessa maneira. Observe que ele captura uma exceção específica e tenta adicionar informações para que uma mensagem mais significativa seja propagada. Observe também que a exceção interna ainda é mantida para fins de registro
ATUALIZAÇÃO Kanini pergunta se é correto ter esse bloco de exceção na camada de dados ou se a verificação do arquivo está disponível para a camada de negócios.
Bem, primeiro eu gostaria de salientar que a lógica para Wrapping Exceptions é esta
Portanto, se você acha que uma camada superior deve saber sobre o arquivo, sua camada de dados deve ficar assim
Não tente não pegar.
Pessoalmente, sinto que, a menos que sua camada de dados possa fazer algo útil, como usar um systems.xml padrão que é um recurso de montagem, não fazer nada ou ocultar a exceção é uma boa aposta, já que o log mostrará qual método e qual arquivo foi o problema. (
throw ex
nesse caso, ou o preferidothrow
também, mas não agrega valor). Isso significa que, uma vez identificado, você poderá resolver o problema rapidamente.Como exemplo, este exemplo em particular também tem o seguinte problema em que XDocument.Load pode lançar quatro exceções
Não podemos garantir com segurança que o código a seguir não será lançado e FileNotFoundException, simplesmente porque ele pode estar lá quando verificamos a existência e desaparecemos quando carregamos. Ter isso disponível para a camada de negócios não ajudaria.
SecurityException é ainda pior, porque, entre outros motivos para isso ser lançado, se outro processo pegar um bloqueio de arquivo exclusivo, você não receberá o erro até tentar abri-lo para leitura, porque não existe o método File.CanIOpenThis (). E se esse método existir, você ainda terá o mesmo problema que o File.Exists
fonte
Vamos fazer uma dramatização. (este não é um post de piada)
Você deve fazer um workshop em que atua na cadeia de chamadas. Cada pessoa é um objeto. Você precisará de alguns iniciantes e algumas pessoas que entendem o "jogo" ajudam.
Use um problema muito simples, como E / S de arquivo. gui-> modelo-> arquivo_io
A pessoa que é o leitor de arquivos precisa informar o próximo ....
Primeiro faça isso com códigos de retorno. (usar post-its?)
se as interações forem apenas "o que o código diz" em breve, você poderá fazer as pessoas perceberem que as exceções são excepcionais.
para códigos de retorno, passe uma nota de post-it.
para exceções, jogue as mãos para o alto e diga qual é o problema.
depois faça com que eles "capturem x, joguem x" e vejam muito pior o diagnóstico é o que a GUI obtém "o modelo teve uma exceção".
Acho que isso funcionará para treinar as pessoas que você tem, porque elas entendem muito bem as interações com outras pessoas.
fonte
Eu imaginaria entender as exceções que você primeiro precisa entender, por exemplo, o relacionamento filho / pai das classes. Se você entender que um filho pode herdar a funcionalidade de um pai, ele poderá, em nível elementar, entender que, se um filho tem um problema que não pode lidar, ele passará esse problema (exceção) para o pai e permitirá que o pai lide. com isso.
Isso se torna uma relação encadeada até você terminar em um lugar onde algo sabe como lidar com a exceção.
E, no que diz respeito finalmente, esta é a parte trivial ... quando ocorre um problema, algo tem que lidar com isso, para que o programa não saia fatalmente, depois que essa exceção é manipulada, o bloco finalmente está lá, que sempre será executado independentemente da tentativa de captura .
Um bom exemplo disso pode ser com redes:
ou em caso de exceção:
fonte
Dê um Aplicativo ao novato que possua muito bom tratamento de exceções. Lance alguma exceção em algum lugar e permita que eles a depurem com a ajuda do Logs. Ao rastrear a propagação da exceção, eles devem poder depurá-la. Faça este exercício 3 ou 4 vezes. Agora basta remover todo o tratamento de exceção do código e permitir que eles tentem rastrear a mesma exceção.
Acredito que a apreciação pelo código de Tratamento de exceções será instantaneamente apreciada.
fonte
Na IMO, você deve pensar que as instruções de tratamento de exceção e controle de fluxo são basicamente as mesmas. Você os utiliza para controlar o fluxo de seus programas com base em quais condições eles estão atualmente. A diferença é que o tratamento de exceções só reagirá quando ocorrer um erro (ou exceção).
fonte
Provavelmente não ajudaria um novo programador, mas descobri que compreendi muito melhor o conceito de exceções quando comecei a usar mônadas na programação funcional. Uma mônada obriga a considerar todos os "canais" pelos quais os dados podem entrar ou sair de um programa, pois tudo isso fornece uma abstração conveniente para "ocultar" parte desse fluxo de dados.
A idéia de que uma função pode ter diferentes tipos de saída e uma exceção é como um tipo de retorno de prioridade mais alta da função é bastante clara.
Entenda, eu entendo que não é assim que as exceções funcionam na maioria dos idiomas (detalhes da implementação), mas em um sentido abstrato, é isso que está acontecendo.
fonte
Finja que um macaco está usando o teclado
Eu costumava dizer aos meus colegas quando eles estavam escrevendo um código para fingir que um macaco estava sentado no teclado e usando esse aplicativo.
Isso os ensinou a antecipar todos os tipos de coisas:
Eu acho que foi a imagem da palavra de ter um macaco apenas apertando teclas e fazendo o que quisesse, em vez de seguir bem o que fez o truque. Funcionou para mim.
fonte