none
Tratamento de Erros C# RRS feed

  • Pergunta

  • Bom Dia

    Tenho um sistema feito em N-Camadas e finalizando na UI feita em MVC 4, faço o tratamento de erros Try {} Catch {} Finaly {} em todas as camadas, mesmo apresentando uma mensagem de erro amigavel ao usuário final, estou tendo problemas de comunicação com a equipe, sempre chega, Suporte o sistema deu erro ! Qua Erro ? Não sei ! o que você estava fazendo ? Nada !

    ai fica dificil resolver,

    Por isto tive a idéia de criar uma classe que herde da System.exception e grave em um arquivo txt todos os detalhes do erro e gere um protocolo e para o usuário final mande uma mensagem do tipo, "ocorreu um erro, entre em contato com o suporte e informe o protocolo xyz" com este protocolo o suporte vai ter acesso a tudo o que aconteceu

    A ideia é ótima, mas quando eu comecei a criar esta classe, toda vez que eu passo o erro para esta classe, eu perco o fluxo do sistema, eu não consigo voltar e continuar de onde eu parei.

    o que pode estar acontecendo

    quarta-feira, 19 de fevereiro de 2014 12:48

Todas as Respostas

  • Olá Alexandre, provavelmente o problema não está na sua classe, e sim na maneira como você está utilizando o bloco try-catch, após o catch ou finally o programa continua o fluxo, a questão é, o que encontra-se programado após eles:

    try{
       instrução 1
       instrução 2
       instrução 3
    }catch(Exception e){
    ...
    }finally{
    
    -> aqui você continua o seu fluxo independente da exceção
    ...
    }
    
    ->aqui pode ser outro block try-catch independente do que der acima
    
    

    Enfim, existem n-combinações que podem ocorrer no tratamento das exceções.

    Abraço.

    quarta-feira, 19 de fevereiro de 2014 13:10
  • Suporte o sistema deu erro ! Qua Erro ? Não sei ! o que você estava fazendo ? Nada !

    Putz, usuários...

    Bom, teria como postar um exemplo de código de como você está fazendo esse tratamento de erros com sua exceção que você criou?

    Só mais uma coisa, é aplicação Web ou Desktop?


    Herbert Lausmann

    quarta-feira, 19 de fevereiro de 2014 13:10
  • Seguindo seu modelo

    try{
       instru
    ção 1
       instru
    ção 2
       instru
    ção 3
    }catch(Exception e){
        TrataErro(e)    --> Aqui vai para a classe que eu criei 
        throw .......    --> Esta linha não executa de jeito nenhum

    }finally{

    -> se tiver passado pela classe TrataErro aqui também não passa
    ...
    }

    quarta-feira, 19 de fevereiro de 2014 15:47
  • Vou dar mais que solução uma opinião!

    Eu não uso Try Catch Finnaly em tudo o que eu faço, porque, isso vai limitar meu sistema a executar sem erros ou ocultar erros de codificação .... O grande problema que eu vejo nos sistemas é que na codificação podemos eliminar todos os erros aparentes e isso que não é feito... uso de Try Catch para mim é um grande problema quando é utilizado na forma que li essa questão logo acima !!!

    Não faça o tratamento em todas as camadas, e coloque somente na sua regra de negócio o resto deixa fluir e ocasinar erros, é bom se vai achar muitas códigos que precisam de manutenção ...

    Bom, porque disso tudo isso, pela experiência de ter pego sistemas para manutenção e quando tem um número excessivo de try catch um acaba anulando/interceptando o outro ... e com tudo isso se não sabe aonde o erro ocorreu ... e muitas vezes é simples a solução ...


    Fulvio Cezar Canducci Dias


    quarta-feira, 19 de fevereiro de 2014 16:03
  • Olá Alexandre.

    Provavelmente seu objeto TrataErro deve estar gerando alguma exceção que está parando por completo o programa.

    Pois utilizando try-catch-finally, em não ocorrendo exceção não tratada no catch, o finally é obrigatório.

    Só um comentário a respeito do uso destes comandos, não é pelo fato de utilizar vários ou em várias camadas é que vai dar problema, a questão é que, se for definida uma arquitetura com a maneira de se tratar os erros um não vai anular o outro.

    Se no seu código, uma vez resolvido a questão se sua codificação da classe TrataErro, e ela fazendo o que você quer, logar o erro e passar pra frente não vai dar problema.

    Acho que a definição de se utilizar numa camada x,y ou z  vai depender de cada cenário.

    quarta-feira, 19 de fevereiro de 2014 19:30
  • Só queria também dar um reforço naquilo que eu escrevi:

    Tem desenvolvedores que fazem assim:

    try
    {
    	int numero = int.Parse("numero");
    }
    catch
    {
    	//Error
    }
    finally
    {
    }

    Ai eu te pergunto existe uma forma correta de se fazer isso para que essa instrução não passe pelo bloco try catch que no meu ver isso é uma código desnecessário, sim existe

    int numero;
    if (int.TryParse("numero", out numero))
    {
    	//passou e não vai precisar usar bloco try catch
    }

    Então reafirmando não é para ser usado em todas as camadas, não é para ser utilizado a torta e a direita, não é para usar isso como codificação do seu código, é para usar em casos especificos, por exemplo, uma verificação de URL aonde os internautas gostam de alterar dados da url só para ocasionar erros de conversão ai se pode usar mas, não classe aonde traz o item você não precisa colocar um try catch se pode verificar se tal código existe se não dê um desvio diferente ao seu código ... 


    Fulvio Cezar Canducci Dias


    quarta-feira, 19 de fevereiro de 2014 20:46
  • Fúlvio, entendi o seu ponto de vista, mas isto aí não é usar, é fazer gambiarra, como lançar throws pra os objetos de fora pegarem e tratarem.

    A pessoa colocar um try-catch e não definir o que fazer com a exceção? Se gerou uma exceção já trás um certo overhead no processamento, então, pensar em trabalhar com exceções pode parecer simples quando o cenário é simples.

    E na minha concepção, existir uma linha de código que possa gerar uma exceção e o desenvolvedor não prever isto, também não é uma boa prática.

    Ou seja, se existe um método que pode gerar um sqlexception (por exemplo) e não existir try-catch nele, pelo menos na assinatura tem que existir esta possibilidade (throws SqlException), para que, quem o chame, saiba o que pode acontecer.

    quarta-feira, 19 de fevereiro de 2014 20:55
  • Fúlvio, entendi o seu ponto de vista, mas isto aí não é usar, é fazer gambiarra, como lançar throws pra os objetos de fora pegarem e tratarem.

    A pessoa colocar um try-catch e não definir o que fazer com a exceção? Se gerou uma exceção já trás um certo overhead no processamento, então, pensar em trabalhar com exceções pode parecer simples quando o cenário é simples.

    E na minha concepção, existir uma linha de código que possa gerar uma exceção e o desenvolvedor não prever isto, também não é uma boa prática.

    Ou seja, se existe um método que pode gerar um sqlexception (por exemplo) e não existir try-catch nele, pelo menos na assinatura tem que existir esta possibilidade (throws SqlException), para que, quem o chame, saiba o que pode acontecer.

    Bahia, desculpa falar mas, eu discordo de você, o uso de try catch não deve ser utilizado como solução e o exemplo que eu dei é um simples exemplo só para você ver a capacidade de que o próprio desenvolvedor pode ocasionar o erro ... então usar desenfreiado eu discordo pacas, meus sites são feitas praticamente 99,5 porcento sem try catch e funciona que é uma beleza ... não me leve a mau, são experiências que eu digo ...

    Obrigado!!!


    Fulvio Cezar Canducci Dias

    quarta-feira, 19 de fevereiro de 2014 20:58
  • Sem problemas, apesar dos poucos pontos aqui, também tenho conhecimento de causa, por isto que te falei, há cenários e cenários.

    Se na arquitetura definida por você quem está chamado "souber" se virar, ok. 

    O que não se pode ter, é um método qualquer não tratar exceção e nem informar na sua assinatura que tipo de exceção ele pode retornar, porque daí, lá fora só vai usar a Exception genérica. 

    A ideia inicial do Alexandre é perfeita, no sentido de melhorar o que ocorre na aplicação para ter um suporte mais refinado, e muitas vezes, o erro (exceção) não ocorre numa camada específica, muitas vezes é por exemplo a camada de apresentação que não soube tratar o um retorno específico que só ocorre com determinados parâmetros, enfim, mas uma vez reitero, o tratar (no sentido de saber fazer algo) exceções muitas vezes não é tão simplório.
    Quando o requisito em cima deste assunto é ínfimo, ou seja, "apenas não deixe a aplicação parar", pode ser que a "preocupação" seja bem menor. Mas até nesta afirmação de exemplo que citei, se formos conversar mais 5 minutos que o autor dela, veremos que não será bem isso. ..

    Valeu! Abraço.



    ---- Ajudou? Marque como útil! :D

    quarta-feira, 19 de fevereiro de 2014 21:22
  • Eu trabalho com Design Patterns, e não é a arquitetura que eu defini, é que as pessoas em modo geral pelas nossas opiniões podem entender tudo errado, no sentido de que Try Catch, oba solução dos meus problemas ... é não é bem assim, agora eu deu um exemplo e acredito que o genérico foi uma suposição e não uma afirmação correta daquilo que não vemos e daquilo que opinamos, mas, eu acredito que pelo enunciado do problema tem rotinas de exceção sem tratamento e sem fundamento no projeto inteiro e isso me preocupa ... !!! Eu uso pouco mesmo e só no sentido de um conexão com banco e/ou rotinas que pode ser aberto aos usuários, do contrário não uso e não acho necessário, são opiniões eu entendo que você quer colocar que ele necessita refinar suas rotinas de exceção e eu já acho que ele tem que diminuir para ter um modelo limpo e mais apropriado para seu projeto.

    Eu gosto de debate porque amplia conhecimento ... 

    Obrigado ... 

    sem mais 


    Fulvio Cezar Canducci Dias

    quinta-feira, 20 de fevereiro de 2014 00:40
  • Concordo com o Fúlvio, já que você não vai tratar todas as exceptions e seu código não deve ter tantas possibilidades de erros assim, você pode dar um Override no "OnException" e nele pode salvar em txt ou em um db:

    protected override void OnException(ExceptionContext filterContext)
    {
        // Bail if we can't do anything; app will crash.
        if (filterContext == null)
            return;
            // since we're handling this, log to elmah
    
        var ex = filterContext.Exception ?? new Exception("No further information exists.");
        LogException(ex);
    
        filterContext.ExceptionHandled = true;
        var data = new ErrorPresentation
            {
                ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
                TheException = ex,
                ShowMessage = !(filterContext.Exception == null),
                ShowLink = false
            };
        filterContext.Result = View("ErrorPage", data);
    }

    fonte: http://stackoverflow.com/questions/812235/error-handling-in-asp-net-mvc

    "just because you've abandoned your hopes of becoming a great thinker or scientist, don't give up on attaining freedom, achieving humility, serving others..." - 7.67 - Meditations - Marcus Aurelius

    quinta-feira, 20 de fevereiro de 2014 11:28
  • Bom, pelo que percebi ele quer preparar o programa dele para reportar um número bem abrangente de possíveis exceções, até porque é como comentei, o erro pode acontecer na apresentação.
    O override é uma solução? é.

    Mas infelizmente no .net não se incorporou uma prática muito boa que existem em outras linguagens OO, o compilador não deveria aceitar este tipo de coisa:

    public void gerarArquivo(String path){

    1. intrução x

    2. instrução y : File.Create(path)

    3. instrução z...

    }

    A assinatura do File.Create está lá, "perfeita" informando quais tipos de exceções este método pode ocasionar, acontece que, o gerarArquivo não trata nada, nem se quer informa pra quem está chamando do que pode acontecer, dando margem a um erro não esperado por quem chama, pois se quando o cara que implementou isso colocasse na assinatura quais os tipos de exceções que gera, ou lançasse uma exceção tratada, com certeza estaria dando uma maior qualidade a um simples método como este.
    O problema é que, o compilador deixa passar, e aí pode ocorrer um efeito cascata num módulo inteiro do sistema, podendo causar inclusive falhas de segurança.

    "A mais o programador pode muito bem só colocar o catch e não fazer nada", aí é outra história, o modelo definido pela linguagem de programação já estaria "forçando" a pessoa a pensar.
    Da mesma forma que é mais prático, analisar exceção de forma genérica que por tipo, isto reflete diretamente na qualidade do software.

    Bom, poderíamos passar horas trocando mensagens que não levariam a nada, isto só se resolve numa reunião conversando e expondo em "tempo de execução" as questões.
    O Alexandre postou a dúvida deve, ele percebeu que existe mais de uma forma, em ambos os caminhos depende de quem vai fazer e como vai fazer para ficar algo com qualidade e de fácil manutenção, entre outras coisas.

    Valeu abraço!


    ---- Ajudou? Marque como útil! :D

    quinta-feira, 20 de fevereiro de 2014 12:43
  • Concordo com o Fúlvio, já que você não vai tratar todas as exceptions e seu código não deve ter tantas possibilidades de erros assim, você pode dar um Override no "OnException" e nele pode salvar em txt ou em um db:

    protected override void OnException(ExceptionContext filterContext)
    {
        // Bail if we can't do anything; app will crash.
        if (filterContext == null)
            return;
            // since we're handling this, log to elmah
    
        var ex = filterContext.Exception ?? new Exception("No further information exists.");
        LogException(ex);
    
        filterContext.ExceptionHandled = true;
        var data = new ErrorPresentation
            {
                ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
                TheException = ex,
                ShowMessage = !(filterContext.Exception == null),
                ShowLink = false
            };
        filterContext.Result = View("ErrorPage", data);
    }

    fonte: http://stackoverflow.com/questions/812235/error-handling-in-asp-net-mvc

    "just because you've abandoned your hopes of becoming a great thinker or scientist, don't give up on attaining freedom, achieving humility, serving others..." - 7.67 - Meditations - Marcus Aurelius

    Parabéns pela sua observação, é nesse ponto mesmo que eu to dizendo e poucos percebem que o erro não ta no uso do try catch e sim na codificação aparente do software, que muitas vezes quem ocasiona o erro é o próprio desenvolvedor !!!
    Obrigado ...

    Fulvio Cezar Canducci Dias



    quinta-feira, 20 de fevereiro de 2014 13:19