Fazer uma PerguntaFazer uma Pergunta
 

Resposta PropostaControle de erros.

  • quinta-feira, 5 de novembro de 2009 13:16Rafael_Lima Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Estou desenvolvendo uma aplicacao em 3 camadas

    Dados
    Negocio
    Apresentaçao para o Usuario

    Estou com algumas dúvidas:
    No tratamento de erro na camada negocio e dados coloco sempre

    try
    ....
    código
    ....
    catch
    throw
    end try

    Com isso trataria os erros na camada de Apresentação, mas alguns erros preciso exibir para o usuario mas outros apenas gravar no log.
    Essa seria a melhor maneira ?


    Na validação de dados poderia tambem gerar uma excessão? Exemplo:
     

    Public Property cpf() As String

     

    Get

        

    Return sCPF

     

    End Get

     

    Set(ByVal Valor As String)

        bValida = ValidaCPF(Valor)

       

    If bValida Then

            sCPF = Valor

       

    Else

     

           Throw (New System.ArgumentException(msgErro, "Numero do CPF"))

       

    End If

     

    End Set

     

    End Property



    Rafael Lima

Todas as Respostas

  • quinta-feira, 5 de novembro de 2009 13:35LeandrodeMelloFagundes Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Resposta Proposta
    Rafael, vamos lá.

    Se você vai executar um try catch throw, não precisa ter o try catch!
    :|

    Só precisa ter se você vai fazer como no exemplo, o throw ser algo específico.

    Bom, agora indo a fundo. Eu prefiro especializar exceptions.
    Tenho as minhas 3 exceptions diferentes. LogicLayerException DataAccessLayerException e GenericUnhandledException.
    Isso apenas para entender e saber aonde executou o problema. Nelas, crio propriedades do tipo "needlog" quando preciso logar, ou então showUserException se quero mostrar pro usuário ou corrigir internamente etc etc.

    No context, adiciono os handlers de threadexception e unhandledexception para métodos privados meu. Onde verifico o tipo da excessão, valido as propriedades, gravo em logs (ou não), mostro em tela (ou não), e finalizo o sistema (quando a continuidade dele pode gerar problemas) ou não.
    Além disso, as telas podem ser personalizadas (cada tipo de exception tem um tipo de tela diferente) e o lugar aonde trato elas é apenas um.

    No resto do código, faço throw new meutipoexception(mensagem,propriedadequandohouve)

    se não quizer tratar nada, deixo correr e no else só mostro uma mensagem genérica (mesma tela quando usar o genericunhandledexception que uso em poucos casos, apenas quando pego uma exception ja existente e quero só mudar o texto por algum motivo ou deixar mais amigável)

    Mais ou menos assim eu faço. Pode ser loucura em algumas partes, mas me trouxe muitos benefícios até hoje
    :)


    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
  • quinta-feira, 5 de novembro de 2009 13:51Rafael_Lima Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     

    Legal isso que estou procurando... gostaria de colocar essa propriedade needlog showUserException mas não sei como implementar :-(


    Poderia ajudar nos enviando um exemplo?



    Obrigado.


    Rafael Lima
  • quinta-feira, 5 de novembro de 2009 15:10Eric Lemes Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Rafael,

    Eu costumo criar uma exceção "minha", business para tratar esse tipo de coisa.

    Ex.: MyBusinessException.

    tudo que vem da camada de negócio e é um erro "interessante" para o usuário, ou seja, não é um erro técnico, eu dou um throw como MyBusinessException.

    Na camada de apresentação eu trato somente exceções do tipo MyBusinessException para voltar o erro para o usuário. As demais (que sõa erros "técnicos"), voltam para o tratamento global de exceção.

    No global.asax eu pego e logo a exceção, via log4net, é claro.


    Abraço,

    Eric
  • quinta-feira, 5 de novembro de 2009 15:27LeandrodeMelloFagundes Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Resposta PropostaContém Código
    Rafael,

    crie uma classe que herda da System.Exception:
    public class MinhaExcecao : System.Exception 
    {
        private bool m_needlog;
    
        public bool NeedLog 
        {
            get { return m_needlog; }
            set { m_needlog = value; }
        }
    }
    
    e em outro lugar qualquer, você instância a minha classe e não o system.exception

    try
    {
        int teste = 1 + 'a';
    }
    catch (System.Exception ex) 
    {
        MinhaExcecao excecao = new MinhaExcecao();
        excecao.NeedLog = true;
    }
    

    Agora, ATENÇÃO:
    Isso foi apenas um exemplo. As  proprieades Message, Data, etc etc etc da classe System.Exception são readonly.
    Então, faça no construtor da sua classe, receber uma system.exception e popule os dados corretamente. Ou algo do gênero.

    O exemplo foi apenas ilustrativo, para você conseguir se basear na idéia.

    Abraços

    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
  • quinta-feira, 5 de novembro de 2009 17:46Rafael_Lima Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    Entendi...


    Agora que comecei a implementar fiquei com outra dúvida:

    Em qual camada eu crio a minha classe MinhaExcecao() ?

    É melhor criar um projeto especifico para isso e colocar a referencia em todas as camadas?


    Vlw

    Rafael Lima
  • quinta-feira, 5 de novembro de 2009 18:46LeandrodeMelloFagundes Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Resposta Proposta
    Rafael, isso é muito questão de preferências!

    Em todo caso, ficam algumas maneiras.
    Eu tenho uma DLL apenas para utilidades minhas. Você tb deve ter. Utilidades comuns. Classes como sei la, formatação de monetário. Ou controles específicos que não são apenas desta aplicação que poderiam ser utilizados em qualquer aplicação. Lá, você pode ter essa exception.
    Ou criar uma dll só pra isso. Apesar de parecer meio FORTE ter uma dll apenas para exceptions, você pode ter outros tipos de mensagem. Eu especializei o messagebox para reduzir o numero de parâmetros por exemplo. Eu tenho o InfoBox.Show que nada mais é que um messagebox com o icone de information, e o CriticalErrorBox.Show que seria o message box com icone de erro.
    apenas para reduzir todos aqueles parâmetros que tem. coisas da minha cabeça maluca! :)
    De qualquer forma, você pode desacoplar o máximo o possível. se um dia tiver outra aplicação, basta referenciar a DLL e pronto
    :) tudo vai estar resolvido hehe

    Fica aqui minha dica. Abraços.


    Ps: se for util, marque como útil, se for resposta, marque como resposta! :) faça o forum um lugar mais fácil para todos!
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler)
  • sábado, 7 de novembro de 2009 14:37Nelson Borges Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Resposta Proposta

    Opa,

    Complementando.. depois que customizar sua exception, e se quiser gravar (anunciado) recomendo utilizar o Enterprise Library, ele te da maior mobilidade depois..

    Ah e quanto aos erros em vários projetos, eu costumo sempre utilizar injeção de dependencia, por isso sempre tenho uma classe que implementa o tratamento de erro generico e  é reutilizado em todas as classes, mas as opções dos amigos são boas tb, se quiser saber mais sobre veja: http://www.codeplex.com/unity/ (ele faz parte do Enterprise Library).


    EL : http://entlib.codeplex.com
    Exemplo de como usar : http://www.codeproject.com/KB/architecture/GetLoggingWithEntLib.aspx


    Abs,


    Nelson Borges - http://nelsonborgesjr.spaces.live.com/blog/ "Ao infinito e além.. "