errorHandler: Gerenciando erros
Projetando um novo sistema, que irá incorporar 5 sub-sistemas, percebi que eu iria precisar de um gerenciamento de erros mais evoluído, e que me fornecesse mais detalhes para lidar com erros encontrados.
Decidi então criar um gerenciador de erros customizado que pudesse gerenciar totalmente os erros do site, tomando as atitudes necessárias quando fosse requisitado. Com ele em etapa de testes agora decidi compartilhar um pouco da experiência.
Na conferência de PHP deste ano (veja aqui , aqui e aqui ) tive a oportunidade de assistir uma palestra do Derick Rethans sobre a biblioteca ezComponents . Um dos componentes me chamou a atenção, o ezcLogger. Este componente responsável por criar logs de ações e erros foi a pedra fundamental do meu gerenciador de erros.
Este componente possui um filtro que pode gravar os erros em logs diferentes de acordo com o seu tipo, ou classificação. Com isso defini os tipos de erros que meu gerenciador ia poder administrar:
- Notice - Um erro que não impede o funcionamento do site, mas alerta sobre alguma ação que mereça ser notada.
- Info - Informação sobre certa ação executada, pode servir de alerta ou estatistica de uso
- Warning - Aviso de erro que não compromete a ação sendo executada, geralmente são erros esperados que não ocasionam perda de dados ou malfuncionamento
- Error - Erro que pode ocasionar perda de dados, porém o sistema é capaz de tratar e se recuperar
- Fatal - Erro irrecuperável que deve ocasionar em rollbacks e travamentos imediatos do sistema. Geralmente são os que geram telas de erro
- Debug - Mensagens de debugagem do código, evita textos de debug aparecendo pelo sistema em produção
- Success Audit - Log de evento que terminou em sucesso, bom para logar ações de scripts rodando em cron
- Failed Audit - Idem porém para atividades que não se completaram
Esta estrutura é a mesma do ezcLogger, e cada erro tem um código baseado em uma constante da classe, exemplo: ezcLog::WARNING
A classe então deveria ter duas funções, uma responsável pelo log da ação e outra gerenciar ações pós erro. No caso de um erro fatal a classe convoca um método que trava o site apresentando uma tela de erro amigável, podendo ou não haver texto customizado para este erro.
Além disso os erros possuem mais dados que são registrados:
- Mensagem - Texto que será escrito no log
- Categoria - Categoria geral do erro (ex: SQL, FileAccess…)
- Source - a fonte do erro, podendo ser desde o nome do arquivo até o sistema ou sub-sistema
Além destes dados que são registrados a função “trigger” (gatilho ou disparar) recebe dados opcionais como uma mensagem amigável que é apresentada no caso de erro fatal. Baseado na categoria do erro o sistema pode também executar outras ações, como por exemplo, no caso de erros SQL buscar o código de erro da conexão para apresentar no log.
Como usar?
O primeiro passo é instanciar o objeto. Faça isso em um ponto central de sue sistema, desta forma a variável estará disponível em todos seus scripts.
$eHandler = new errorHandler();
Agora é só usar o objeto. Durante a programação do sistema, defina os pontos onde erros podem ocorrer, e prepare para tratar estes erros. O resto é simples apenas chame a função trigger passando as variáveis ou dados corretos.
//Disparar erro $eHandler->trigger("403 - Permissão Negada",ezcLog::FATAL,"Acesso",$PHP\_SELF);
//Disparar erros de dentro de Objetos $GLOBALS\['eHandler'\]->trigger("403 - Permissão Negada",ezcLog::FATAL,"Acesso",$PHP\_SELF);
Como esta classe foi desenhada para um sistema específico, alguns detalhes não são “genéricos”, como poderão observar nas áreas de valores padrões, especialmente de “source”. Mas isso é simples, substitua por PHP_SELF ou algo de sua preferência.
Os Logs
Como poderão observar, criei uma extensão para o ezComponents que escreve em arquivos no formato XML, pois por padrão ele apenas escreve arquivos de texto comum. Esta extensão ainda precisa de um pouco de trabalho, então irei divulgar ela depois, por enquanto recomendo que usem o formato padrão, ou embarquem na loucura comigo.
Qual o problema? Bem o log, para evitar necessidade de leitura antes da escrita, não possui tags de agrupamento, ou um tag “root” do xml. Isso torna o XML inválido, mesmo sendo legível. Mas para isso criei um arquivo simples em PHP que lê o arquivo, envolve em tags e joga pra tela, com isso tenho acesso rápido ao log para identificar erros.
Claro que o próximo passo é desenvolver uma área administrativa de acompanhamento de logs, completa com buscas (obrigado XPath ) e outros detalhes. Mas isso é mais pra frente.
Então era isso que eu tinha para compartilhar, apenas uma visão do pacote, ainda precisa de trabalho, e quando terminar o pacote completo: leitura/escrita; compartilho o script todo com vocês.