web-dev-qa-db-fra.com

Empêcher la journalisation du suivi de pile pour les exceptions personnalisées dans l'application Spring Boot

Existe-t-il un moyen dans Spring Boot (mvc) de enregistrer une exception personnalisée et la lever sans que sa trace de pile soit visible dans le journal fichier? Mais pour toute autre exception, voyez toujours la trace de la pile.

Explication longue:

J'utilise Spring Boot pour créer un service de repos simple. J'aime que pour les exceptions personnalisées, il n'y ait pas de trace de pile dans les journaux par défaut et la réponse json est créée avec les détails de base de l'exception (état, erreur, message).

Le problème est que cela ne crée pas non plus de journal entrée, donc je devrais le faire manuellement:

Exception personnalisée

@ResponseStatus(value = HttpStatus.CONFLICT)
public class DuplicateFoundException extends RuntimeException {
    public DuplicateFoundException(String message) {
        super(message);
    }
}

Exception lors du lancement de la méthode de service (dans @RestController)

if (!voteDao.findByItemAndUser(item, voteDto.getUserId()).isEmpty()) {
    log.warn("... already voted ...");   //TODO: don't do this for every throw
    throw new DuplicateFoundException("... already voted ...");
}

Avoir plus d'exceptions conduit à placer l'instruction log avant chaque lancer, ce qui est une mauvaise approche, je pense. J'ai essayé de supprimer toutes les instructions de journal de la méthode de service et créé @ ControlledAdvice où je journaliserais toutes les exceptions personnalisées et je les relance juste pour que j'obtienne toujours le json Nice comme avant:

@ControllerAdvice
public class RestExceptionHandler {
    private static final Logger log = Logger.getLogger(RestExceptionHandler.class);

    @ExceptionHandler
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            log.warn(e.getMessage());
        } else {
            log.error("...");
        }
        throw e;
    }
}

Maintenant, le problème est que je vois non seulement l'entrée de journal, mais aussi la trace de la pile pour les exceptions personnalisées et je ne peux pas trouver un moyen d'empêcher cela. Je pense que le problème est causé par le lancer à nouveau. Une solution possible pourrait être de créer une classe d'exception personnalisée que je reviendrai à la place, mais je n'aime pas l'idée car le triage des exceptions semble fonctionner correctement.

Des indices? Merci.

19
rhorvath

La solution consistait à laisser la gestion des exceptions au démarrage de printemps, afin que l'exception personnalisée ne soit pas enregistrée et que toute autre soit enregistrée par défaut. J'ai supprimé @ControllerAdvice et aussi les instructions de journalisation du contrôleur de repos et instruction de journalisation ajoutée au constructeur d'exceptions personnalisé.

public DuplicateFoundException(String message) {
    super(message);
    LOGGER.warn(message);
}

Je ne suis pas sûr que ce soit la meilleure approche, mais maintenant je n'ai la journalisation des exceptions personnalisée qu'à un seul endroit et je n'ai plus à répéter l'instruction log pour chaque exception ou à voir sa trace de pile ou tout autre message d'erreur dans les journaux.

1
rhorvath

J'utilise Spring Boot 2+, ajoutez simplement cette ligne à votre application.

server.error.include-stacktrace = jamais

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/web/ErrorProperties.IncludeStacktrace.html

13
Carlos Negron

Si vous n'avez pas besoin de la trace de pile, vous pouvez supprimer la trace de pile en remplaçant fillInStackTrace dans votre classe d'exception.

public class DuplicateFoundException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

Lorsque vous appelez e.printStackTrace(), aucune trace de pile ne sera imprimée.

Voir aussi cet article de blog .

9
Roland Weisleder