set_exception_handler()
Como set_exception_handler() do PHP registra um tratador global para exceções não capturadas, cobrindo assinatura, valor de retorno e exemplos.
Introdução
set_exception_handler() registra uma função que o PHP chama sempre que uma exceção não capturada chega ao topo do script. Normalmente, uma exceção não capturada produz um erro fatal e um rastreamento de pilha padrão; um tratador global permite substituir isso por registro consistente, uma página de erro amigável ou alertas — em um único lugar, para toda a aplicação. Esta página cobre a assinatura da função, o que ela retorna, um exemplo executável, os casos que ela não cobre e os detalhes importantes a saber.
Se você precisar primeiro dos conceitos básicos sobre lançar e capturar exceções, comece com Exceções PHP e o capítulo try/catch.
Quando o tratador é chamado?
Uma exceção normal é capturada pelo bloco catch correspondente mais próximo. O tratador global só é executado quando nenhum bloco catch corresponde — a exceção "escapa" completamente do script:
try {
throw new RuntimeException('handled here');
} catch (RuntimeException $e) {
// caught locally — the global handler never runs
}
throw new RuntimeException('nothing catches this'); // → global handler runs, then script endsApós o retorno do tratador, a execução não é retomada — o script é encerrado. Portanto, o tratador é sua última chance de registrar e apresentar a falha de forma limpa, não uma maneira de recuperar e continuar.
Assinatura e valor de retorno
set_exception_handler(?callable $callback): ?callable$callback— um callable que aceita o objeto lançado como único argumento. Desde o PHP 7, toda exceção e erro implementaThrowable, então defina o tipo do parâmetro comoThrowable(não apenasException) para também capturar instâncias deError, comoTypeError.- Retorna o tratador anteriormente registrado (ou
nullse nenhum foi definido), que você pode guardar para restaurar mais tarde. Passarnullremove o tratador.
Exemplo executável
O script abaixo registra um tratador, o aciona com uma exceção não capturada e exibe uma mensagem formatada. Ele escreve no erro padrão via error_log() sem destino, portanto é totalmente portável:
<?php
function appExceptionHandler(Throwable $e): void
{
$message = sprintf(
"Uncaught %s: %s in %s on line %d",
get_class($e),
$e->getMessage(),
$e->getFile(),
$e->getLine()
);
error_log($message); // goes to the SAPI error log / stderr
echo "Something went wrong.\n"; // user-facing message
}
set_exception_handler('appExceptionHandler');
throw new RuntimeException('Database is unreachable');Saída (a linha error_log vai para stderr, o echo para stdout):
Something went wrong.com uma linha como Uncaught RuntimeException: Database is unreachable in /path/to/script.php on line 19 no log de erros.
O que ele NÃO trata
set_exception_handler() intercepta apenas exceções não capturadas. Ele não captura:
- Erros fatais, erros de análise ou avisos — esses passam por
set_error_handler()(para erros capturáveis) ouregister_shutdown_function()(para fatais). - Exceções que já foram capturadas por um
try/catchlocal.
Para erros que não são exceções, como avisos e notificações, registre um tratador separado com set_error_handler().
Restaurando o tratador anterior
restore_exception_handler() reverte para o tratador que estava ativo antes da sua última chamada a set_exception_handler(). Use-o quando um tratador personalizado deve ser aplicado apenas a um bloco específico de código:
<?php
set_exception_handler(function (Throwable $e) {
echo "Custom: {$e->getMessage()}\n";
});
// ... code that should use the custom handler ...
restore_exception_handler(); // back to the default behaviorImportante: seu tratador não deve lançar uma nova exceção. Se lançar, o PHP não consegue despachá-la novamente e gera um erro fatal.
Boas práticas ao usar set_exception_handler
Ao usar set_exception_handler, há algumas boas práticas que você deve seguir para garantir que sua aplicação lide com erros de forma eficaz:
- Defina o tipo do parâmetro do tratador como
Throwablepara capturar tanto subtipos deExceptionquanto deError(PHP 7+). - Certifique-se de que o tratador nunca lance uma nova exceção — isso aciona um erro fatal irrecuperável.
- Registre contexto suficiente para diagnosticar a falha: classe da exceção, mensagem, arquivo, linha e o rastreamento de pilha de
$e->getTraceAsString(). - Mantenha a mensagem voltada ao usuário genérica; nunca exponha rastreamentos de pilha ou mensagens aos usuários finais em produção.
- Registre o tratador o mais cedo possível (por exemplo, em um arquivo de inicialização) para que ele cubra toda a requisição.
- Combine-o com
set_error_handler()eregister_shutdown_function()para cobrir também avisos, notificações e erros fatais. - Use
restore_exception_handler()para reverter ao tratador anterior quando um personalizado deve ter escopo limitado a um bloco de código.
Conclusão
set_exception_handler() oferece um único lugar para tratar todas as exceções não capturadas em uma aplicação — transformando um erro fatal bruto em registro consistente e uma mensagem amigável ao usuário. Lembre-se dos seus limites: ele é executado apenas para exceções não capturadas, a execução é encerrada após ele, e o próprio tratador nunca deve lançar exceções. Combine-o com set_error_handler() para avisos, trigger-error para sinais de erro personalizados e restore_exception_handler() para tratamento com escopo limitado, a fim de construir um sistema de relatório de erros robusto.