web-dev-qa-db-fra.com

Comment pourrions-nous utiliser @ExceptionHandler avec Spring Web Flux?

Au printemps web, nous pourrions utiliser l'annotation @ExceptionHandler pour gérer les erreurs de serveur et de client pour les contrôleurs.

J'ai essayé d'utiliser cette annotation avec le contrôleur web-flux et cela fonctionnait toujours pour moi, mais après quelques recherches, j'ai découvert ici

La situation avec Spring Web Reactive est plus compliquée. Parce que les flux réactifs sont évalués par un thread différent de celui qui exécute la méthode controllers, les exceptions ne seront pas propagé au thread du contrôleur automatiquement. Cela signifie que le La méthode @ExceptionHandler ne fonctionnera que pour les exceptions levées dans le thread qui gère directement la demande. Exceptions levées le flux devra être propagé au thread si nous voulons utilisez la fonctionnalité @ExceptionHandler. Cela semble un peu décevant mais au moment d'écrire ces lignes, le printemps 5 n'est toujours pas publié, donc la gestion des erreurs pourrait encore s'améliorer.

Donc, ma question est de savoir comment propager une exception sur le thread. Existe-t-il un bon exemple ou un article sur l'utilisation de @ExceptionHandler et du flux Web Spring?

Mise à jour: De spring.io il semble que cela soit pris en charge, mais manque encore de compréhension générale

Merci,

5
Evgen

Vous pouvez utiliser des méthodes annotées @ExceptionHandler pour gérer les erreurs survenant lors de l'exécution d'un gestionnaire WebFlux (par exemple, votre méthode de contrôleur). Avec MVC, vous pouvez également gérer les erreurs survenues pendant la phase de mappage, mais ce n'est pas le cas avec WebFlux.

De retour à votre question de propagation d'exception, l'article que vous partagez est inexact.

Dans les applications réactives, le traitement de la requête peut en effet passer d'un thread à un autre à tout moment, vous ne pouvez donc plus vous fier au modèle "un thread par requête" (pensez: ThreadLocal).

Vous n'avez pas à penser à la propagation des exceptions ni à la gestion des threads. Par exemple, les exemples suivants doivent être équivalents:

@GetMapping("/test")
public Mono<User> showUser() {
  throw new IllegalStateException("error message!);
}


@GetMapping("/test")
public Mono<User> showUser() {
  return Mono.error(new IllegalStateException("error message!));
}

Reactor enverra ces exceptions en tant que signaux d'erreur comme prévu dans le contrat de flux réactifs (voir la section "Traitement des erreurs" pour plus d'informations à ce sujet).

6
Brian Clozel

pas une réponse exacte à la question initiale, mais un moyen rapide de mapper vos exceptions sur le statut de réponse http consiste à lancer org.springframework.web.server.ResponseStatusException/ou à créer vos propres sous-classes ...

Un contrôle total sur l'état de la réponse http + spring ajoutera un corps de réponse avec la possibilité d'ajouter un reason.

{
    "timestamp": 1529138182607,
    "path": "/api/notes/f7b.491bc-5c86-4fe6-9ad7-111",
    "status": 400,
    "error": "Bad Request",
    "message": "For input string: \"f7b.491bc\""
}
1
Hartmut