Pergunta

Este é escrito em PHP, mas é realmente agnóstico linguagem.

try
{
    try
    {
        $issue = new DM_Issue($core->db->escape_string($_GET['issue']));
    }
    catch(DM_Exception $e)
    {
        throw new Error_Page($tpl, ERR_NOT_FOUND, $e->getMessage());
    }
}
catch(Error_Page $e)
{
    die($e);
}

é tentativa aninhada, blocos catch uma boa prática a seguir? Parece um pouco volumoso apenas para uma página de erro -. No entanto o meu problema DataManager lança uma exceção se ocorrer um erro e eu considero que para ser uma boa maneira de detectar erro

A exceção Error_Page é simplesmente um compilador de página de erro.

Eu só poderia ser pedante, mas você acha que isso é uma boa maneira de relatar erros e se assim você pode sugerir uma maneira melhor para escrever este?

Graças

Foi útil?

Solução

Você está usando exceções para a lógica da página, e eu pessoalmente acho que não é uma coisa boa. Exceções devem ser usados ??para sinalizar quando o mau ou coisas inesperadas acontecem, não para controlar a saída de uma página de erro. Se você deseja gerar uma página de erro com base em exceções, considere o uso set_exception_handler . Quaisquer exceções.Ele são executados através de qualquer método de retorno de chamada especificado. Tenha em mente que isso não impede que o "fatalness" de uma exceção. Após uma exceção é passada através de seu retorno de chamada, a execução irá parar como normal após qualquer exceção não capturada.

Outras dicas

Eu acho que você seria melhor fora de não nidificação. Se você esperar vários tipos de exceção, têm múltiplas capturas.

try{
  Something();
}
catch( SpecificException se )
{blah();}
catch( AnotherException ae )
{blah();}

O ideal é que as exceções de ser pego no nível que pode lidar com eles. Não antes (desperdício de tempo), e não depois (você contexto perder).

Então, se $ tpl e ERR_NOT_FOUND são informações que só é "conhecido" perto da nova chamada DM_Issue, por exemplo, porque há outros lugares onde você cria uma DM_Issue e gostaria ERR_SOMETHING_ELSE, ou porque o valor de US $ tpl varia , então você está pegando a primeira exceção no lugar certo.

Como chegar a partir desse lugar para morrer é outra questão. Uma alternativa seria a morrer ali mesmo. Mas se você fizer isso, então não há nenhuma oportunidade para intervir código para fazer qualquer coisa (como limpando alguma coisa de alguma forma ou modificar a página de erro) após o erro, mas antes de sair. Também é bom ter controle de fluxo explícito. Então eu acho que você é bom.

Estou assumindo que o seu exemplo não é uma completa aplicação - se for, então provavelmente é desnecessariamente detalhada, e você poderia apenas morrer na cláusula DM_Exception captura. Mas para uma aplicação real eu aprovo o princípio da não apenas morrendo no meio do nada.

Dependendo de suas necessidades isso poderia ser bom, mas eu sou geralmente muito hesitantes para capturar uma exceção, enrole a mensagem em uma nova exceção, e relançar-lo porque você perder o rastreamento de pilha (e potencialmente outras) informações da exceção original no excepção de embrulho. Se você é certeza que você não precisa essa informação ao examinar a exceção de embrulho então provavelmente é certo.

Eu não tenho certeza sobre o PHP, mas no exemplo C # você pode ter mais de um catch-bloco por isso não há necessidade de try / catch combinações aninhadas.

Geralmente eu acredito que ErrorHandling com try / catch / finally é sempre bom senso, também para mostrar "apenas" um erro de página. É uma maneira limpa para erros tratar e evitar comportamento estranho em deixar de funcionar.

Eu não iria lançar uma exceção em questão não foi encontrado - é um estado válido de um aplicativo, e você não precisa de um rastreamento de pilha apenas para exibir um 404.

O que você precisa captura é fracassos inesperados, como erros de SQL - que é quando o tratamento de exceção vem a calhar. Gostaria de alterar o código se parecer mais com isto:

try {
    $issue = DM_Issue::fetch($core->db->escape_string($_GET['issue']));
}
catch (SQLException $e) {
    log_error('SQL Error: DM_Issue::fetch()', $e->get_message());
}
catch (Exception $e) {
    log_error('Exception: DM_Issue::fetch()', $e->get_message());
}

if(!$issue) {
    display_error_page($tpl, ERR_NOT_FOUND);
}
else
{
    // ... do stuff with $issue object.
}

As excepções devem ser usados ??apenas se houver um evento potencialmente local quebrar - como uma consulta de banco de dados não executar corretamente ou algo está mal configurado. Um bom exemplo é que um diretório de cache ou log não é gravável pelo processo Apache.

A idéia aqui é que as exceções são para você, o desenvolvedor, ao código impasse que pode quebrar todo o site para que você possa corrigi-los antes da implantação. Eles são também checagens para se certificar de que, se o ambiente muda (ou seja, altera alguém as permissões da pasta de cache ou mudar o esquema de banco de dados) o site é interrompido antes que possa danificar nada.

Assim, não; manipuladores de captura aninhados não são uma boa idéia. Em minhas páginas, meu arquivo index.php envolve seu código em um bloco try ... esconderijo - e se algo de ruim acontece ele verifica para ver se o seu na produção ou não; e tanto me e-mails e exibir uma página de erro genérica, ou shows o direito de erro na tela.

Lembre-se: PHP não é C #. C # é (com a exceção (hehe, sem trocadilhos: p) de ASP.net). Para aplicações que contenham estado - enquanto PHP é uma linguagem de scripting sem estado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top