2017-10-03 6 views
1

Je travaille sur un service qui envoie des emails en utilisant l'intégration de printemps java dsl.Traitement des erreurs après un séparateur de messages avec des canaux directs

J'ai un message de lot qui est divisé en une collection de messages individuels qui seront transformés en courriels.

Le problème que je rencontre est que si l'un de ces messages individuels renvoie une erreur, les autres messages du lot ne sont pas traités.

Existe-t-il un moyen de configurer le flux de sorte que lorsqu'un message déclenche une exception, l'exception est gérée correctement et le message suivant dans le lot est traité?

Le code suivant réalise la fonctionnalité que je voudrais, mais je me demande s'il existe un moyen plus facile/meilleur d'y parvenir, idéalement dans un seul IntegrationFlow? :

@Bean 
    public MessageChannel individualFlowInputChannel() { 
     return MessageChannels.direct().get(); 
    } 

    @Bean 
    public IntegrationFlow batchFlow() { 
     return f -> f 
      .split() 
      .handle(message -> { 
       try { 
        individualFlowInputChannel().send(message); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      }); 
    } 

    @Bean 
    public IntegrationFlow individualFlow() { 
     return IntegrationFlows.from(individualFlowInputChannel()) 
      .handle((payload, headers) -> { 
       throw new RuntimeException("BOOM!"); 
      }).get(); 
    } 

Répondre

0

Vous pouvez ajouter ExpressionEvaluatingRequestHandlerAdvice à la dernière définition handle() avec son option trapException:

/** 
* If true, any exception will be caught and null returned. 
* Default false. 
* @param trapException true to trap Exceptions. 
*/ 
public void setTrapException(boolean trapException) { 

D'autre part, si vous parlez « envoie des e-mails », ne serait-il mieux envisager de le faire dans le fil séparé pour chaque élément divisé? Dans ce cas, le ExecutorChannel après .split() vient à la rescousse!

+1

Merci Artem. Le conseil ne s'applique qu'à la définition 'handle()', n'est-ce pas? Je voudrais être robuste contre les exceptions de tout composant en aval aussi bien. Je suis d'accord que l'approche 'ExecutorChannel' est probablement la meilleure approche et je vais envisager d'utiliser cela dans le futur – DMurphy

+0

Right, que' ExpressionEvaluatingRequestHandlerAdvice' est vraiment appliqué uniquement pour le 'handleRequstMessage' - la portée de l'actuel' AbstractReplyProducingMessageHandler'. Si vous voulez "piéger" toute l'exception en aval, vous devez implémenter votre propre "HandleMessageAdvice". Sinon non, toutes les exceptions dans le même thread sont lancées et arrêtent en effet le prochain traitement d'élément partagé –