Corrigir bugs requer muita experiência e conhecimento dos módulos envolvidos, tanto técnico como funcional. O primeiro passo para consertar alguma coisa é procurar a causa do problema, também conhecido como debugging (processo metódico de localizar e corrigir erros em um código de programa de computador).

Você não deve se limitar a usar o debugger somente quando as coisas dão errado, você também pode usar para entender o sistema, eu freqüentemente uso para entender como é o funcionamento standard do sistema e então aplicar as novas modificações necessárias para atingir os resultados solicitados por meus clientes. O Debugger ajuda a saber como implementar as modificações e quais as conseqüências. Que fique bem claro, o Dynamics AX é muito grande e muito complexo para você apenas fazer modificações pequenas sem saber ao certo o que está fazendo.

Abaixo algumas dicas para ajudar você na fina arte de debugar. Algumas talvez sejam grosseiramente obvias para desenvolvedores experientes, mas são dicas que eu gostaria de ter quando comecei com o AX.

Então vamos lá:

Assuma, você quem estragou!
Este provavelmente é o conselho mais importante. Nós desenvolvedores temos tendência a pensar que escrevemos bons códigos. Alguns de nós realmente escrevemos, mas ninguém faz isso sem cometer erros ou deixar espaços para discussões do tipo “poderia ser melhor“. Por padrão, assuma que você não escreve códigos perfeitos, isto irá limitar a procura por erros consideravelmente. Após debugar você provavelmente terá uma conclusão diferente.

Se o sistema estava rodando e de repente parou após você importar um código novo, o novo código provavelmente é a causa do problema. Procure remover exatamente as modificações que você fez, caso o problema persista, você encontrou um problema não relatado anteriormente, caso contrário, você sabe onde começar a procurar por erros.

Seja o Sr. Chato! Tenha uma descrição muito clara do problema.
A menos que o erro esteja claro o suficiente e você saiba imediatamente como resolver o problema, você precisará de uma descrição detalhada de como reproduzir este erro. Infelizmente isso pode ser bem difícil. Pedir aos usuários para explicar a você exatamente o que você precisa para entender sobre o problema não é uma tarefa fácil. Tenha em mente que os usuários geralmente não estão interessados nos programas que eles usam, eles simplesmente querem usar, querem que funcione e que o trabalho deles termine logo. Eles foram ensinados a usar o sistema de uma certa forma e erros inesperados podem confundi-los. Eles talvez não entendam qual é a diferença quando as coisas dão errado comparadas com quando tudo está ok.

Você precisa fazer as perguntas corretas, se necessário, sentar perto do usuário e vê-lo trabalhar. Faça anotações e tente perceber os casos especiais, que fogem do normal. Não se esqueça também de perguntar qual a comportamento normal que o sistema deveria ter. Talvez não exista uma mensagem de erro e aconteça o que acontecer talvez pareça tudo OK, mas o usuário espera um resultado diferente.

Sem um bom cenário, talvez seja impossível resolver alguns bugs.

Não se preocupe muito com erros que aconteceram apenas uma vez.
Se alguma coisa deu errado apenas uma vez e não acontece novamente, não se preocupe muito. Há provavelmente em algum lugar bugs ocultos, mas você tem que decidir se vale a pena correr atrás.

Intercepte a mensagem de erro
Tudo que foi para a janela de log passou através do método add() dentro da classe Info. Coloque um breakpoint neste método se você deseja saber onde o erro foi gerado. Usando o Stack Trace no debugger torna a procura por onde o erro foi gerado bem mais fácil.

Intercepte a modificação dos dados.
Nem todos os problemas vem com uma maneira fácil de interceptar as mensagens de erro. Algumas vezes tudo que você tem são dados errados. É possível ver quando e porque os registros são criados, modificados ou removidos colocando um breakpoint nos métodos insert(), update() ou delete() na tabela. Sobrescreva os métodos se for necessário. Basta ser capaz de olhar para o stack trace no debugger quando estes métodos são chamados.

Lembre-se que é possível alterar dados sem passar através desses método, como usando o doIsert(), doUpdate() ou doDelete(), ou ainda usando diretamente SQL. Não é muito comum, mas algumas vezes você pode esquecer-se de algo.

Intercepte as queries.
Se você suspeita que uma query não está correta, você precisará verificar seu output. Um caminho que não requer muito trabalho é usando o método postLoad(). Ele pode ser sobrescrito em cada tabela e é chamado para cada registro selecionado. Também funciona com Joins complexos. Colocando um info no método postLoad() de cada tabela da query irá te dizer muita coisa sobre “o que está acontecendo“.

A cross-reference é sua amiga.
A cross-reference é uma das mais importantes ferramentas quando você está desenvolvendo ou debugando no Dynamics AX. Sempre tente ter um ambiente com a cross-reference atualizada (não no ambiente de produção)
Precisa saber onde o campo pega seu valor? A cross-reference te fala onde cada leitura e escrita acontece.
Quer saber onde uma mensagem de erro é usada? Abra o editor de etiquetas, encontre o Label e então clique no botão “Usado por“.

Configure um ambiente separado
Quando tratamos com problemas complexos isto ajuda se você tem um ambiente separado para debugar. Este procedimento permite a você modificações livres no código e nos dados sem afetar o ambiente de produção. É muito importante quando você tem que postar notas fiscais, diários e etc que não são reversíveis ou que tem a reversão complicadas.

Isto também permite que usuários do ambiente de produção sejam bloqueados por seus breakpoints no meio de suas transações.

Lidando com muitos dados
Algumas vezes um problema só é possível de ser reproduzido em uma cópia do ambiente de produção. Você freqüentemente estará preso com uma quantidade enorme de dados que não ajuda, mas este é o caminho. Como quando você precisa debugar o MRP. Usando breakpoints não irá ajudar muito porque existe muita coisa antes do problema real.

Neste caso você precisa ter mais truques na manga para reduzir a pesquisa. Uma opção é trabalhar em vários passos. Usando a cross-reference determinamos lugares onde coisas interessantes acontecem e se você visualizar os dados usando info() ou no Debug::printDebug(). Isto deve estreitar e muito as possibilidades suspeitas. Com um pouco de sorte, procurar apenas nos dados pode ser o suficiente para identificar o problema.

Outro caminho é implementar seus breakpoints condicionais. O debugger não oferece estes recursos, mas você pode fazer você mesmo com uma instrução if e então uma instrução breakpoint. Este processo é muito efetivo se você tem mais ou menos identificadores únicos para o problema, como um record ID ou uma conta de cliente ou até mesmo uma data.

Limpeza
Não se esqueça de remover qualquer modificação que você fez enquanto estava debugando. Você provavelmente não deseja que um breakpoint inserido no código apareça no ambiente de produção. Lembre-se que isso é muito chato.

Mensagens de debug profissionais
Temos a tendência de quando não estamos conseguindo resolver o problema de colocar mensagens chulas no meio do código que com certeza iremos esquecer e elas acabarão sendo exibidas quando o cliente estiver testando.

Boa sorte caçando bugs.

Sinta-se livre para compartilhar conosco suas técnicas de debugging.

Artigo traduzido e alterado baseando-se no artigo original:
http://sysdictcoder.com/blog/10-tips-for-debugging-in-dynamics-ax/