2016-02-19 113 views
0

我目前在一個抽象類中進行了異常處理,我的所有路由都繼承了異常處理。類似這樣的:Grails中的駱駝異常處理

onException(SocketException,HttpOperationFailedException) 
     .handled(true) 
     .maximumRedeliveries(settings.maximumRedeliveries) 
     .redeliverDelay(settings.redeliverDelay) 
     .useCollisionAvoidance() 
     .collisionAvoidanceFactor(settings.collisionAvoidanceFactor) 
     .onRedelivery(redeliveryProcessor) 
     .log('retry failed, sending to the route failed coordinator') 
     .to(routeFailedCoordinator) 

現在,我想根據不同的響應代碼做一些不同的事情。對於除200以外的所有代碼,引發HttpOperationFailedException get。對於4XX代碼,如果啓用了特定路由,我希望將該消息發送到失敗的隊列併發送電子郵件。對於所有其他錯誤,我想通過重試周期。以下是適用於4XX錯誤的內容:

onException(HttpOperationFailedException) 
     .handled(true) 
     .process { Exchange x -> 
      HttpOperationFailedException ex = x.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class) 
      log.debug("Caught a HttpOperationFailedException: statusCode=${ex?.statusCode}") 
      ProducerTemplate producer = x.getContext().createProducerTemplate() 
      if (ex?.statusCode >= 400 && ex?.statusCode < 500) { 
       log.debug("Skipping retries ...") 

       producer.send(routeFailedEndpoint, x) 

       x.in.body = "Request:\n${x.in.body}\n\nResponse: ${ex.statusCode}\n${ex.responseBody}".toString() 
       if (sendFailedEmailEnabled) 
        producer.send('direct:routeFailedEmailHandler', x) 
      } else { 
       producer.send(routeFailedRetryEndpoint, x) 
      } 
     }.stop() 

如何在第一個代碼段中添加用於重試的代碼?我嘗試使用嵌套choice()... when()...否則()子句和不斷收到編譯錯誤。

任何人都必須做類似的事情?

這裏是我的代碼嵌套選擇()。當()..否則,()的條款:

onException(HttpOperationFailedException) 
     .handled(true) 
     .choice() 
      .when { Exchange x -> 
       HttpOperationFailedException ex = x.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class) 
       log.debug("Caught a HttpOperationFailedException: statusCode=${ex?.statusCode}") 
       if (ex?.statusCode >= 400 && ex?.statusCode < 500) { 
        log.debug("Skipping retries ...") 
        x.in.body = "Request:\n${x.in.body}\n\nResponse: ${ex.statusCode}\n${ex.responseBody}".toString() 
        return true // don't retry 
       } 

       log.debug("Performing retries ...") 
       return false // do attempt retries 
      }.choice() 
       .when { !sendFailedEmailEnabled }.to(routeFailedEndpoint) 
       .otherwise() 
        .multicast().to(routeFailedEndpoint, 'direct:routeFailedEmailHandler').endChoice() 
      .otherwise() 
       .getParent().getParent().getParent() 
       .maximumRedeliveries(settings.maximumRedeliveries) 
       .redeliverDelay(settings.redeliverDelay) 
       .useCollisionAvoidance() 
       .collisionAvoidanceFactor(settings.collisionAvoidanceFactor) 
       .onRedelivery(redeliveryProcessor) 
       .to(routeFailedCoordinator) 

回答

0

你就必須有2塊onException的:

  • 一個onException與用於重新傳送嘗試的重新傳送設置
  • 另一個onException處理異常併發送該電子郵件以及您想要執行的操作。
  • 在兩個onException塊上使用onWhen,在基於該http狀態碼的任一情況下返回truefalse。當由駱駝執行時,知道要使用哪個onException塊(可以有更多的,但首先使用返回true)。

您可以在駱駝網站或駱駝在行動書中找到更多詳細信息,該書有專門討論錯誤處理的完整章節。

+0

謝謝,克勞斯。我會給我一個鏡頭。 – emiles

0

謝謝你,克勞斯,你指出我在正確的方向。

基本上,克勞斯說,使用多個onException的塊,每個塊使用onWhen子句...

onException(HttpOperationFailedException) 
     .onWhen(new Predicate() { 
      public boolean matches(Exchange exchange) { 
       HttpOperationFailedException ex = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class) 
       log.debug("Caught an HttpOperationFailedException: statusCode=${ex?.statusCode}, processing 4XX error") 
       return (ex?.statusCode >= 400 && ex?.statusCode < 500) 
      } 
     }).handled(true) 
      .to(routeFailedEndpoint) 
      .choice() 
       .when { sendFailedEmailEnabled }.process(prepareFailureEmail).to('direct:routeFailedEmailHandler') 

    onException(HttpOperationFailedException) 
     .onWhen(new Predicate() { 
      public boolean matches(Exchange exchange) { 
       HttpOperationFailedException ex = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, HttpOperationFailedException.class) 
       log.debug("Caught an HttpOperationFailedException: statusCode=${ex?.statusCode}, processing >=500 error") 
       return (ex?.statusCode >= 500) 
      } 
     }).handled(true) 
      .maximumRedeliveries(settings.maximumRedeliveries) 
      .redeliverDelay(settings.redeliverDelay) 
      .useCollisionAvoidance() 
      .collisionAvoidanceFactor(settings.collisionAvoidanceFactor) 
      .onRedelivery(redeliveryProcessor) 
      .to(routeFailedCoordinator)