Quando se trata uma exceção, o correto é:
- Ou envolver a exceção em uma nova exceção, passando mais informações;
- Ou tratá-la, logando a exceção e exibindo ao usuário, quando for o caso.
Mas nunca os dois (relançar e logar). Considere o Servlet abaixo. Neste exemplo, este é o nível mais alto da operação, então o papel do tratamento de exceção é informar ao usuário (logar e enviar uma mensagem para o Response).
public class ClienteServlet ... ... public void gravarCliente(ServletRequest req, ServletResponse res) { try { DAOCliente.gravar(criaClienteVo(req)); } catch (RuntimeException e) { log.error("Erro ao salvar cliente", e); res.setAttribute("error", "Erro. Contate suporte."); } catch (BusinessException e) { log.error("Erro de negócio ao salvar cliente", e);
res.setAttribute("error", "Erro ao salvar cliente "
+ e.getMessage());
}
}
}
Exemplo de Antipattern 1
No caso de um código que loga e relança, como o código abaixo, teremos a saída mostrada na sequência. Note que a exceção é mostrada 2 vezes, mas de maneiras diferentes.
public class DAOCliente ... ... public void gravar(ClienteVo cliente) throws BusinessException { try { ... ... COMANDO INSERT ... } catch (SQLException e) { log.error("Erro ao salvar cliente", e); throw new BusinessException("Erro no banco", e); } } }
13:40:02 [ERROR] Erro ao salvar cliente
java.sql.SQLException: ORA-00001: unique constraint ... at oracle.driver...SomeOracleDriverClass() at DAOCliente.gravar(DAOCliente.java:50) at ClienteServlet.gravarCliente(ClienteServlet.java:85) 13:40:02 [ERROR] Erro de negócio ao salvar cliente
BusinessException: Erro no banco at DAOCliente.gravar(DAOCliente.java:63) at ClienteServlet.gravarCliente(ClienteServlet.java:85) Caused by: java.sql.SQLException: ORA-00001: unique constraint ... at oracle.driver...SomeOracleDriverClass() at DAOCliente.gravar(DAOCliente.java:50) ... 2 more
Exemplo de Antipattern 2
Ou ainda como o código abaixo, exatamente a mesma exceção é logada 2 vezes.
public class DAOCliente ... ... public void gravar(ClienteVo cliente) { try { ... ... COMANDO INSERT ... } catch (SQLException e) { log.error("Erro ao salvar cliente, e); throw new e; } } }
13:40:02 [ERROR] Erro ao salvar cliente java.sqlSQLException: ORA-00001: unique constraint ... at oracle.driver...SomeOracleDriverClass() at DAOCliente.gravar(DAOCliente.java:50) at ClienteServlet.gravarCliente(ClienteServlet.java:85) 13:40:02 [ERROR] Erro de negócio ao salvar cliente java.sql.SQLException: ORA-00001: unique constraint ... at oracle.driver...SomeOracleDriverClass() at DAOCliente.gravar(DAOCliente.java:50) at ClienteServlet.gravarCliente(ClienteServlet.java:85)
Código esperado
O código deve OU relançar uma exceção (caso seja um nível intermediário ou inferior) OU logar e informar ao usuário (caso seja o nível superior). No exemplo abaixo, como não é a classe de nível superior, ela deve apenas relançar a exceção. Com isso, o log fica com apenas uma única ocorrência.
public class DAOCliente ... ... public void gravar(ClienteVo cliente) { try { ... ... COMANDO INSERT ... } catch (SQLException e) { throw new BusinessException("Erro no banco", e); } } }
13:40:02 [ERROR] Erro de negócio ao salvar cliente BusinessException: Erro no banco at DAOCliente.gravar(DAOCliente.java:63)
at ClienteServlet.gravarCliente(ClienteServlet.java:85) Caused by: java.sql.SQLException: ORA-00001: unique constraint ... at oracle.driver...SomeOracleDriverClass() at DAOCliente.gravar(DAOCliente.java:50) ... 2 more
Nenhum comentário:
Postar um comentário