Tratamento de erros é sempre um ponto negligenciado por muitos desenvolvedores. Quem nunca se deparou com um bloco catch
vazio? Neste post vou iniciar uma abordagem deste assunto com ênfase na camada SOA.
Abordagens
Vou apresentar duas abordagens com seus prós e contras. Esta análise é importante pois é comum vermos decisões de arquitetura sendo tomadas ou defendidas sem embasamento, também conhecido como metodologia ‘goela abaixo’. Por isso costumo apresentar dois caminhos sempre que possível, assim o cliente pode verificar o que melhor se adapta à sua realidade.
Neste caso, a alternativa apresentada seria utilizar ou não o SOA Pattern Exception Shielding
1. Com o uso de Exception Shielding
Este pattern consiste em filtrar detalhes da exceção a fim de evitar que eles comprometam a segurança do ambiente.
O ponto positivo deste pattern é não expor detalhes de implementação para o consumidor. Quem não lembra os famosos erros não tratados que expunham usuário e senha do banco de dados na interface web?
O ponto de atenção é que sua implementação pode prejudicar a identificação e solução de erros devido a falta de informação sobre os mesmos enviadas ao consumidor.
Para contornar este ponto, o sistema onde o erro foi originado deve logar o erro completo juntamente com uma chave única, que será retornada ao consumidor. Desta forma, quando um erro se manifesta o usuário pode encaminhar esta chave única do erro para a equipe de sustentação, facilitando assim a identificação do mesmo.
2. Sem o uso de Exception Shielding
Esta segunda estratégia é mais simples e mais frequentemente utilizada. Nela todos os detalhes do erro, como stack trace, são compostos na mensagem e retornados ao(s) consumidor(es). Este(s), por sua vez, deve(m) garantir que tais detalhes não sejam exibidos ao usuário final.
Implementação mais simples;
Fácil troubleshooting;
Exposição de detalhes de implementação dos provedores aos consumidores, muitas vezes parceiros ou externos.
Mesmo mais simples, muitas vezes nem este nível de tratamento de erros é implementado em grande parte dos casos. É comum encontrar sistemas que enviam mensagens genéricas aos consumidores e a única forma de troubleshooting é com acesso a log da aplicação, o que muitas vezes não está acessível a equipe.
Conclusão
O uso deste pattern deixa a solução mais bem acabada, porém requer uma maior maturidade e estrutura para disponibilizar uma forma adequada de troubleshooting. Então é natural iniciar de forma mais simples, mas acredito ser importante caminhar para a padronização do tratamento de erros, tanto em termos de mensagem ao usuário final (que não foi abordado neste post) quanto com relação a geração e consulta dessa chave única para o troubleshooting.
É importante ressaltar que independente da abordagem utilizada é importante ter uma estrutura padronizada para retornar estes dados. Caso seja SOAP
seria através de um elemento no detail
do SOAP Fault. Caso seja REST, utilizar o HTTP Status Code correto e retornar uma estrutura JSON padronizada com mais detalhes.
Já conhecia estas estratégias? O que utiliza na sua empresa? Vamos continuar o assunto nos comentários 😉
Felipe, bem didática e objetiva sua explicação sobre o assunto, parabéns.
Você acredita que esta decisão pode ser deixada para um segundo momento, ou seja, implemento num primeiro momento e então, busco a melhor prática?
Ainda falando do pattern, concordo com a primeira abordagem, desde que haja uma boa estrutura e que seja uma referencia estressada ao máximo.
Obrigado Diego!
Você mesmo deu a resposta 😉
Mas ao ler seu comentário percebi que algo importante não ficou claro no conteúdo do post:
Considero o uso do pattern obrigatório em caso de exposição de serviços a parceiros e exposição de ‘API’ públicas.
Respondendo sua pergunta, o ótimo é inimigo do bom! Então a não ser que se enquadre no cenário acima (Parceiro/API) muitas vezes é mais viável iniciar com um modelo padronizado de tratamento de erros, para depois partir para o Exception Shielding. Mas é importante implementar a segunda abordagem corretamente, isso não deveria ser tão desafiador/custoso.