Comendo Exceções com Farinha

Há alguns meses eu passei por dias bem corridos. Precisávamos fazer a entrega de um grande produto e, como sempre, tudo resolve acontecer nos últimos dias, resultando numa lista de bugs que precisam ser corrigidos. O maior problema desta lista era um bug aparentemente simples, um include JSP que não funcionava. Acotnece que este código foi herdado de uma famosa empresa indiana CMM nível 5 e, como tal, está uma porcaria.

Como não havia tempo para refatorar o sistema (diria que 90% dele precisava mudar, isso caracteriza reescrita ou ainda posso chamar de refactoring?), tivemos que trabalhar com o que tínhamos em mãos. E o que tínhamos em mãos era: enderecodosistema.empresa.com.br, o endereço do próprio servidor. Essa era aúnica mensagem de erro, na verdade era algo assim que aparecia no log:

javax.servlet.ServletException: enderecodosistema.empresa.com.br
at atg.portal.framework.taglib.RenderPreparedGearTag.doStartTag()
at jsp_servlet._templates._claclacal._html.__full._jspService()
at weblogic.servlet.jsp.JspBase.service()V(Optimized Method)
at weblogic.servlet.internal(Optimized Method)
...

Detalhe que o erro só ocorria no servidor de produção, justo o que não podíamos manipular sem preecncher 15 formulários em várias vias. Após olhar o código (cada mais fundo que eu ia mais palavrões soltava e minha cara de espanto atraía os transeuntes) eu percebi que o sistema era baseado num padrão de projeto muito famoso em empresas, principalmente as consultorias com CMM, chamado “Vamos-Comer-Esta-Exceção-Com-Farinha”.

O código era mais ou menos assim (claro que isso era copiado e colado algumas milhares de vezes por todo o código, modularidade para quê?):


try{
algumaCoisaQualquer();
}
catch(Exception e){
String msg = e.getMessage();
throw new BussinesRuleException(msg);
}

Muito bom! Nossa mensagem simplesmente podia ser QUALQUER coisa. O tipo da exceção foi perdido, a stacktrace foi perdido… a única coisa que ficou foi o CMM nível 5.

Solução? Primeiro tentamos adicionar mais debugging. Isso podia dar certo mas ia demorar uma semana para conseguirmos colocar o sistema em produção com um log decente (i.e. StackTraces), fora o tempo de correção após termos descoberto o que acotnecia. Como o problema só ocorria em produção, um bom ponto de partida seria verificar se tudo que está neste servidor está em outros (o pessoal de infra sempre diz que tá, maaaas…).

Compara daqui, compara de lá e… dezenas de biblitoecas com versões diferentes. Uma coisa interessante é que haviam duas versões do Jalarta Commons HttpClient, removemos a versão anterior, consolidamos todas as bibliotecas, configurações e DataSources e… nada!

Após a derrota na hipótese das versões de bibliotecas, estava almoçando com meu chefe enquanto fazíamos uma chamada para os gerentes que podiam autorizar nossa versão com log melhorado ir para produção quando me deu um estalo. Ora, se tem HTTP client neste sistema e se a mensagem de erro é o hostname… ELE ESTA TENTANDO FAZER UMA CONEXÃO HTTP LOOPBACK! Acontece que o sistema estava em pré-produção, logo seu DNS não estava registrado. Aquela exceção só podia ser algo do tipo new HostNotFoundException("enderecodosistema.empresa.com.br");.

Relendo todo o código, suspeita confirmada. Uma linha no /etc/hosts e o sistema estava pronto para entrar em produção.

Agora, por que raios ele se conectava a ele mesmo? Lendo direito eu percebi que um dos programadores CMM nível 5 utilizava uma JSP para gerar um arquivo XML que era transformado via XSLT em HTML. Ou seja: ele precisava se conectar novamente para dar um GET na página JSP que retornava o arquivo! Ele usava uma tecnologia utilizada para criar HTML (JSP) apr agerar um XML que era transformado em HTML!

Qualquer API de XML meia-boca vai te dar um método que retorna o XML gerado como uma String mas acho que nosso amigo CMM nível 5 não sabia ler JavaDocs em inglês.

Eu poderia tentar concluir com uma reflexão sobre o design de aplicações, umas dicas básicas para trabalhar com XMl em uma aplicação web ou sei lá o que, mas em vez disso eu vou terminar com uma lição simples: cuidado com as mensagens das suas exceções, você nunca vai saber quando uma consultoria CMM nível 5 vai utilizar seu código.

Faça sua mensagem de exceção contêr pelo menos alguma coisa de útil caso não haja stacktraces nem o tipo da exceção esteja disponível. Eu sei que no caso reportado o problema não foi da API (afinal, HostNotFoundException: “host not found enderecodosistema.empresa.com.br” é, no mínimo, prolixo) mas pense que nem todas as pessoas que vão usar seu código são programadores, alguns são apenas CMM nível 5.

15 Responses to “Comendo Exceções com Farinha”

  1. Rubem Azenha says:

    O CMM(i) garante que todo o desenvolvimento seguiu um processo formal e integro, que inclui analise de requisitos, projeto, implementação, testes, homologação e que cada processo foi executado seguindo um determinado padrão. Não significa que o programador (que executa apenas um processo) seja melhor ou pior do que um programador CMM(i).
    Não da pra generalizar e dizer que todas as empresas CMM(i) nivelam por baixo o nível dos programadores.
    Do mesmo modo que você tem bons e maus programdores em empresas não-CMM(i), você tem bons e maus programdores em empresas CMM(i).

  2. Rubem, o problema é que existe um mito (pelo menos entre o pessoal mais leigo, a.k.a gerência) de que CMM(i) nível X == perfeição, o nível dos profissionais é só um detalhe insignificante, né? O importante é que “O Processo” seja seguido.

    Philip, parece que vc deu de cara c/ um anti-pattern muito comum entre certos desenvolvedores, talvez podemos chamá-lo de Exception-Aniquiliator-Tabajara anti-pattern :)

    Essa semana encontrei algo parecido num código de outra pessoa, a diferença é que era muito pior: o código simplesmente fazia um catch(Exception e) numa action do struts, dava um println no getMessage() e saía na boa! Acredita?

  3. pcalcado says:

    Ótimo, se CMMx não garante que meu produto final tem qualidade ele garante o que? Que o mesmo código ruim é reprodutível?

    Para que eu vou pagar o adicio0nal de CMMx se o produto final não tem qualidade?

    Aliás, mesmo o processo neste caso não foi nem um pouco exemplar, mas vamos nos ate ao que importa: o código gerado e o valor agregado ao cliente.

  4. pcalcado says:

    Willian,

    Acho que tínhamos dois anti-patterns então, o comedor de exceções e o Struts >:D

  5. Rubem Azenha says:

    Não tem como garantir a qualidade de nada.
    Mas também o CMM(i) não garante a falta da qualidade.
    Os processos CMM(i) tem coisas legais que se seguidas dão certo.
    Pensando bem, é provável que esse software foi criado por uma empresa com certificação CMM(i) mas não seguiu alguns principios do CMM(i) como inspeção e testes extensivos.

  6. Rubem Azenha says:

    Willian, me desculpe, acabei não vendo o seu comentário.
    Realmente isso pode acontecer. Mas é claramento um erro e não nescessáriamente ocorre.
    Pessoas de maior visão com certeza perceberão isso.

  7. Rubem, “Não tem como garantir a qualidade de nada.”

    Que tal contratando uma equipe decente de desenvolvimento ao invés de pagar por uma sopa de letrinhas que não agrega nada se não processos burocráticos ao ciclo de desenvolvimento?

  8. Rubem Azenha says:

    É uma boa :)
    Se contratar uma equipe decente e tiver bons processos\metodologias de trabalho é melhor ainda.

  9. Eu sofri recentemente com esse esquema de exceptions abafadas por outras e ainda, estou sofrendo com hierarquias de exceptions complemente… erhm… deixa pra lá.

    Quando tive problema com o “Exception-Aniquiliator-Tabajara” - se o William me permite - fui um tanto quando radical. Procurei por todas as chamadas ao construtor que recebia apenas a mensagem e corrigi todas onde a causa era abafada.

    Sobre o ultimo comentário do Rubem, bons profissionais conseguem compensar a falta de metodologia, mas metodologias, por melhores que sejam, não conseguem compensar a falta de bons profissionais. É aquela velha historia de que “a fool with a tool is still a fool”.

  10. RodrigoSol says:

    Rubem,

    IMHO, profissionais decentes se sentem entediados com processos / metodologias burocráticas e deixam de ser decentes( em menos de 3 meses).

  11. Rubem Azenha says:

    Marcos, você disse que “bons profissionais conseguem compensar a falta de metodologia”. Talvez para um projeto menor. Mas em projetos grandes com vários módulos e várias integrações entre eles, com grandes equipes, se faz nescessário que pelo menos algumas normas sejam definidas.

    É óbvio que nada dispensa um bom profissional e que é um erro achar que os processos tornam a qualidade técnica um mero detalhe.

    Eu só não gostei da genereliação, falar que todos os profissionais de empresas que adotam CMMx são mulas bestas incompetentes.

    RodrigoSol, defina exatamente processos burocráticos :)
    Trabalho em uma empresa que adotou CMM e não considero o meu trabalho extremamente burocrático. Talvez uma vez ou outra tenha uma pequena complicação, mas eu acho que é devido até a natureza do software que desenvolvemos. Não da para desenvolver um software grande como o nosso sem definir alguns processos para determinadas tarefas.

  12. pcalcado says:

    Realmente a falta de processo (confusão de nomenclatura aí…) é um problema mas o ponto é que não importa o quão bom seu processo seja, ele não compensa profissionais ruins. Como na verdade a grande maioria das empresas, incluindo a maioria das que eu conheço que se vangloriam de seus CMMx, baseiam seus modelos de negócio em utilizar centenas de programadores ruins (não são todos, pra você não se ofender achando que estou generalizando) com um processo burocrático que tenta compensar este fato.

    Bem, não compensa e isso pode se ver olhando para o lado. Qualquer lado.

    O problema não é ter processo, pelo contrário. Os problemas são:

    1 - Achar que um processo bem definido compensa mão-de-obra ruim
    2 - Achar que certificações sobre processos, ferramentas ou programadores garantem alguma espécie de qualidade
    3 - Modelos de negócio baseados no ‘me engana que eu gosto’, mas este será outro post.

  13. Rubem Azenha says:

    “3 - Modelos de negócio baseados no ‘me engana que eu gosto’, mas este será outro post.”

    Hum, estou curioso para ver esse post :)

  14. Zé Ricardo says:

    Os colegas já disseram bem.

    Não existe programador CMM nível 5. CMM é uma referência à maturidade do processo de desenvolvimento de softwares.

    Realmente as empresas em alto nível de CMM são bastante organizadas e, jamais, permitiriam que uma falha grosseira como essa (sistema não funciona em produção) chegasse ao cliente.

    Se você, como consultor, foi contratado antes do problema ter chego ao cliente, com o projeto ainda no prazo estipulado, pode dizer que a empresa que desenvolveu o produto tem excelência. Afinal, em meio a um problema que poderia afetar o relacionamento direto com o cliente, ela dicidiu prontamente contratar uma consultoria especializada. Caso tenha sido depois, ou seja, o cliente recebeu um produto defeituoso, você pode dizer que houve uma falha no processo horroroso, digna de fazer os auditores ficarem de cabelo em pé.

    Mas eu não entendo porque os programadores adoram códigos organizados mas amam processos caóticos. E, outra, o processo é ótimo, os grandes projetos de todas as áreas do conhecimentos se referenciam neles. O problema é que tudo pode ser hackeável e aí já viu.

    Do mais, aprecio muito suas soluções e o seu site. Parabéns!

    Zé Ricardo

  15. pcalcado says:

    Sim, foi um produto defeituoso mas… quem disse que programadores apreciam processos caóticos? Eles apreciam processos que agregam algo, não (necessariamente) certificado.