Como Usar Exceptions e Tratamento de Erros em PHP em Produção Já leu

Entendendo Exceptions em PHP 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. Em PHP, toda exception herda da classe ou . Quando algo incomum acontece, você pode lançar uma exception usando , e o fluxo normal do programa é interrompido até que alguém capture essa exception com . Isso oferece um mecanismo muito mais poderoso do que simplesmente retornar false ou verificar status codes. Estrutura Try-Catch-Finally Try O bloco 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 apropriado. Catch O bloco captura e trata a exception. Você pode ter múltiplos blocos para diferentes tipos de exceptions, permitindo tratamentos específicos. O PHP tenta fazer match com a classe da exception na

Entendendo Exceptions em PHP

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.

Em PHP, toda exception herda da classe Exception ou Throwable. Quando algo incomum acontece, você pode lançar uma exception usando throw, e o fluxo normal do programa é interrompido até que alguém capture essa exception com try-catch. Isso oferece um mecanismo muito mais poderoso do que simplesmente retornar false ou verificar status codes.

<?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();
}

Estrutura Try-Catch-Finally

Try

O bloco try 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 catch apropriado.

Catch

O bloco catch captura e trata a exception. Você pode ter múltiplos blocos catch 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.

Finally

O bloco finally é opcional mas muito útil. Ele sempre executa, independente de ter havido exception ou não. Use para limpar recursos, fechar conexões ou executar ações essenciais.

<?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";
}

Criando Exceptions Customizadas

Criar suas próprias exceções torna o código mais legível e permite tratamentos muito mais específicos. Basta estender a classe Exception e, se necessário, adicionar propriedades ou métodos extras.

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.

<?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";
}

Boas Práticas e Tratamento de Erros

Não Suprima Exceptions

Nunca use @ para suprimir warnings ou erros. Isso esconde problemas reais. Se você quer ignorar uma exception de verdade, faça isso explicitamente no catch.

Registre Erros

Sempre faça log de exceptions em produção. Use error_log() ou bibliotecas como Monolog para rastrear o que deu errado.

Não Abuse de Try-Catch

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.

Propague Quando Apropriado

À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.

<?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()]);
}

Conclusão

Exceptions são a forma moderna e recomendada de lidar com erros em PHP. Os três pontos principais a levar para casa: (1) use try-catch-finally para capturar e tratar erros de forma controlada; (2) crie suas próprias exception classes para representar erros específicos do seu domínio, tornando o código mais semântico; (3) combine exceptions com boas práticas de logging e nunca suprima erros com @.

Dominar esse tema é essencial para construir aplicações robustas que se comportam de forma previsível mesmo quando algo inesperado acontece.

Referências


Artigos relacionados