如何处理 onException 中的异常并传播到 Apache Camel 中的 errorHandler?

问题描述 投票:0回答:1

我正在运行一个案例,由于数据库中断而发生异常, 然后调用 onException 处理程序,它尝试在数据库中存储一条消息并更新一些状态,这显然也因为中断而失败。

我想要一个额外的全局异常处理程序,用作后备。并使用 errorHandler()

声明它

这是产生失败的 onException 处理程序,我想到了一个想法:

通过在发生故障时将handled 设置为 false,异常应该向上传播到下一个处理程序。

我用 handled(false) 启动 onException 子句,运行处理器,如果没有发生异常,则 handled(exchange -> true)

但是,这里的执行顺序不一样!查看每行附加的数字

      //would love to catch here
      errorHandler(deadLetterChannel("direct:errorRoute")
        .maximumRedeliveries(1) // Optional: set redelivery attempts
        .onRedelivery(exchange -> {
           log.debug("Redelivery");
         })
      );
        
        //or here
        onException(Throwable.class)
          .process(exchange -> {
            //not called
          });

        //or here
        from("direct:errorRoute")
            .routeId("errorRoute")
            .process(exchange -> {
                   //not called
                });

        from("actual-route")
           //exception handler failing because of database outage
           .onException(Exception.class)
              //delegate to top-level by default
              .handled(false)
  
              .process(notifier::notify)#2
              .process(tracker::onProcessingFailed) //#3 this fails

              //Idea: Only executed when all process commands run without exception
              .handled(exchange -> true) #1
           .end()
           .process(processorFailingBecauseDatabaseOutage)

顶级错误处理程序从未被调用,而是调用FatalFallbackErrorHandler

我需要做什么才能将异常成功传播到顶级处理程序?

error-handling apache-camel spring-camel
1个回答
0
投票

这里有一些关于死信通道内抛出异常的内容。

Apache Camel - 死信频道

作为替代方案,可以使用附加的异常子句。

        from("timer:test-timer?repeatCount=1")
        .onException(Exception.class)
            .handled(true)
            .log("Local Exception!")
            .onException(Exception.class)
                .log("Manage specific process exception")
            .end()
            .throwException(new CamelException("Process Exception"))
        .end()
        .throwException(new IllegalArgumentException("DB Outage Exception"))
        .log("Not Getting here!");

如果这不能说服您,我将在您的流程中使用 try-catch 并使用 ProducerTemplate 发送异常/交换。

    from("direct:error-log")
        // Handle the Exception
        .log("Exception: ${exception}");

    from("timer:test-timer?repeatCount=1")
        .onException(Exception.class)
            .handled(true)
            .log("Local Exception!")
            .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    try {
                        throw new CamelException("Process Exception");
                    } catch (Exception e) {
                        exchange.setProperty(Exchange.EXCEPTION_CAUGHT, e);
                        exchange.getContext()
                            .createProducerTemplate()
                            .send("direct:error-log", exchange);
                    }
                }
            })
        .end()
        .throwException(new IllegalArgumentException("DB Outage Exception"))
        .log("Not Getting here!");

无论如何,请告诉我你的意见。

问候。

© www.soinside.com 2019 - 2024. All rights reserved.