Ainda é um antipadrão se registrarmos uma mensagem de exceção e lançarmos uma exceção diferente?

18

Nosso aplicativo da web está usando um ExceptionMapperpara mapear algumas exceções Response. Registramos as mensagens de exceção antes de lançar uma nova exceção da seguinte maneira:

catch (SomeException ex) {
  LOG.error(ex.getMessage());
  throw new MyException(ex.getMessage());
}

Não estamos lançando novamente a mesma exceção , então minha pergunta é se isso seria considerado um antipadrão de Log and Throw . E, portanto, seria melhor remover o log em locais semelhantes e movê-los para as várias ExceptionMapperclasses da seguinte maneira:

@Provider
public class MyExceptionMapper implements ExceptionMapper<MyException> {

  // bla bla 

  @Override
  public Response toResponse(final MyException ex) {
    LOG.error(ex.getMessage());
    return Response.status(400).entity("something").build();
  }
}
Diyarbakir
fonte
3
Eu pararia você assim que você logasse ex.getMessage(), isso já está errado.
biziclop 02/09/2015
Na IMO, não é justo não mencionar que este é um serviço da web. Isso realmente muda as regras do jogo, porque, por exemplo, o uso de mecânicas regulares de tratamento de exceções pode ser um risco à segurança; você não deseja que toda e qualquer exceção seja enviada de volta em uma resposta de erro 500, que precisa ser verificada e filtrada. O registro agressivo no local também é muito mais comum quando se lida com sistemas que possuem clientes externos que o invocam diretamente. O registro de rastreamentos de pilha em chamadas de serviço que são invocadas repetidamente pode levar a tamanhos de arquivos de log não gerenciáveis ​​e problemas de desempenho.
@Gimby Nesse caso, o OP não envia nenhum detalhe de erro na resposta (provavelmente um conteúdo clichê "ocorreu um erro"). Além disso, como você diagnostica um problema sem um rastreamento de pilha? Os registradores rotativos costumam cuidar do tamanho do armazenamento e os dados do log são embaraçosamente compactáveis.
Marko Topolnik

Respostas:

36

Seu código, na verdade, ostenta não um, mas três antipadrões:

  1. registrar e relançar;
  2. relance novamente sem envolver a causa original;
  3. registre apenas a mensagem e não o stacktrace (esse é o pior).

Se você seguiu a melhor prática para:

  1. não pegar nada (deixe a exceção propagar por conta própria);
  2. se forçado a capturar uma exceção verificada, envolva-a em desmarcado e repita;
  3. nunca registre nada, exceto no nível superior;
  4. registre todo o stacktrace de exceção com log.error("Error occurred", e);

você não enfrentaria nenhum dilema, incluindo o atual, porque o stacktrace registrado também incluiria todas as exceções agrupadas.

Marko Topolnik
fonte