<h2>Entendendo Exceptions em PHP</h2>
<p>Uma exception (exceção) é um objeto que representa um erro ou uma situação excepcional durante a execução do código. Diferente dos erros tradicionais, as exceptions podem ser capturadas e tratadas de forma elegante, permitindo que sua aplicação continue funcionando ou termine de forma controlada.</p>
<p>Em PHP, toda exception herda da classe <code>Exception</code> ou <code>Throwable</code>. Quando algo incomum acontece, você pode lançar uma exception usando <code>throw</code>, e o fluxo normal do programa é interrompido até que alguém capture essa exception com <code>try-catch</code>. Isso oferece um mecanismo muito mais poderoso do que simplesmente retornar false ou verificar status codes.</p>
<pre><code class="language-php"><?php
try {
$idade = -5;
if ($idade < 0) {
throw new Exception("Idade não pode ser negativa!");
}
echo "Idade válida: " . $idade;
} catch (Exception $e) {
echo "Erro capturado: " . $e->getMessage();
}</code></pre>
<h2>Estrutura Try-Catch-Finally</h2>
<h3>Try</h3>
<p>O bloco <code>try</code> contém o código que pode gerar uma exception. Se uma exception for lançada dentro dele, a execução pula imediatamente para o bloco <code>catch</code> apropriado.</p>
<h3>Catch</h3>
<p>O bloco <code>catch</code> captura e trata a exception. Você pode ter múltiplos blocos <code>catch</code> para diferentes tipos de exceptions, permitindo tratamentos específicos. O PHP tenta fazer match com a classe da exception na ordem em que os catches aparecem.</p>
<h3>Finally</h3>
<p>O bloco <code>finally</code> é opcional mas muito útil. Ele <strong>sempre</strong> executa, independente de ter havido exception ou não. Use para limpar recursos, fechar conexões ou executar ações essenciais.</p>
<pre><code class="language-php"><?php
class UsuarioNaoEncontradoException extends Exception {}
class PermissaoNegadaException extends Exception {}
function buscarUsuario($id) {
if ($id < 1) {
throw new UsuarioNaoEncontradoException("ID inválido");
}
if ($id === 999) {
throw new PermissaoNegadaException("Acesso negado para este usuário");
}
return ["id" => $id, "nome" => "João"];
}
try {
$usuario = buscarUsuario(999);
echo "Usuário: " . $usuario["nome"];
} catch (UsuarioNaoEncontradoException $e) {
echo "Erro de busca: " . $e->getMessage();
} catch (PermissaoNegadaException $e) {
echo "Erro de segurança: " . $e->getMessage();
} catch (Exception $e) {
echo "Erro genérico: " . $e->getMessage();
} finally {
echo "\n[Log] Operação finalizada";
}</code></pre>
<h2>Criando Exceptions Customizadas</h2>
<p>Criar suas próprias exceções torna o código mais legível e permite tratamentos muito mais específicos. Basta estender a classe <code>Exception</code> e, se necessário, adicionar propriedades ou métodos extras.</p>
<p>Exceptions customizadas funcionam especialmente bem em grandes projetos onde você quer comunicar erros de negócio diferentes (erro de validação, erro de autenticação, erro de banco de dados, etc). Cada uma pode ter seu comportamento próprio.</p>
<pre><code class="language-php"><?php
class ValidacaoException extends Exception {
private $campo;
public function __construct($campo, $mensagem = "") {
$this->campo = $campo;
parent::__construct($mensagem ?: "Campo '$campo' inválido");
}
public function getCampo() {
return $this->campo;
}
}
class BancoDadosException extends Exception {}
function validarEmail($email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new ValidacaoException("email", "Formato de e-mail inválido");
}
}
function conectarBD() {
throw new BancoDadosException("Falha ao conectar no servidor");
}
try {
validarEmail("email-invalido");
conectarBD();
} catch (ValidacaoException $e) {
echo "Campo com erro: " . $e->getCampo() . " - " . $e->getMessage();
} catch (BancoDadosException $e) {
echo "Problema na base de dados, tente mais tarde";
error_log($e->getMessage()); // Log interno
} finally {
echo "\n[Limpeza] Recursos liberados";
}</code></pre>
<h2>Boas Práticas e Tratamento de Erros</h2>
<h3>Não Suprima Exceptions</h3>
<p>Nunca use <code>@</code> para suprimir warnings ou erros. Isso esconde problemas reais. Se você quer ignorar uma exception de verdade, faça isso explicitamente no catch.</p>
<h3>Registre Erros</h3>
<p>Sempre faça log de exceptions em produção. Use <code>error_log()</code> ou bibliotecas como Monolog para rastrear o que deu errado.</p>
<h3>Não Abuse de Try-Catch</h3>
<p>Try-catch é poderoso, mas não deve envolver todo seu código. Use apenas onde realmente espera exceptions. Um try-catch excessivo prejudica a legibilidade.</p>
<h3>Propague Quando Apropriado</h3>
<p>Às vezes é melhor deixar a exception subir na pilha para ser tratada em um nível superior (como um handler global) do que tentar tratar localmente.</p>
<pre><code class="language-php"><?php
function processarPagamento($valor) {
if ($valor <= 0) {
throw new Exception("Valor deve ser maior que zero");
}
try {
$resultado = chamarAPIGateway($valor);
return $resultado;
} catch (Exception $e) {
// Log da falha
error_log("Erro ao processar pagamento: " . $e->getMessage());
// Re-lança a exception para ser tratada acima
throw new Exception("Não foi possível processar o pagamento", 0, $e);
}
}
// No controlador/handler principal
try {
$resultado = processarPagamento(100);
echo "Pagamento realizado com sucesso";
} catch (Exception $e) {
http_response_code(400);
echo json_encode(["erro" => $e->getMessage()]);
}</code></pre>
<h2>Conclusão</h2>
<p>Exceptions são a forma moderna e recomendada de lidar com erros em PHP. Os três pontos principais a levar para casa: <strong>(1)</strong> use <code>try-catch-finally</code> para capturar e tratar erros de forma controlada; <strong>(2)</strong> crie suas próprias exception classes para representar erros específicos do seu domínio, tornando o código mais semântico; <strong>(3)</strong> combine exceptions com boas práticas de logging e nunca suprima erros com <code>@</code>.</p>
<p>Dominar esse tema é essencial para construir aplicações robustas que se comportam de forma previsível mesmo quando algo inesperado acontece.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.php.net/manual/en/language.exceptions.php" target="_blank" rel="noopener noreferrer">PHP Manual - Exceptions</a></li>
<li><a href="https://www.php.net/manual/en/ref.errorfunc.php" target="_blank" rel="noopener noreferrer">PHP Manual - Error Handling</a></li>
<li><a href="https://www.php-fig.org/psr/psr-3/" target="_blank" rel="noopener noreferrer">PSR-3: Logger Interface</a></li>
<li><a href="https://github.com/Seldaek/monolog" target="_blank" rel="noopener noreferrer">Monolog - Logging for PHP</a></li>
<li><a href="https://www.oreilly.com/library/view/clean-code-a/9780136083238/" target="_blank" rel="noopener noreferrer">Clean Code: A Handbook of Agile Software Craftsmanship - Robert C. Martin</a></li>
</ul>