We are using camel as ESB and noticed something breaking after 4.7.x release.
The "onException" registered in routes are not working. Control won't flow into this block but works fine in versions prior to 4.7.x. Was there any breaking api change introduced in this version?
I have attached the very small boot gradle project to replicate the scenario. In build.gradle just switch the camel version and you can see the difference.
If you use version prior version to 4.7, everything works as excepted. The below code will print "exception caught!!" and returns a 200 OK response. But if you upgrade to 4.7.x or later, the control won't reach in to the onException block and rest response returns a 500 response.
URL : http://localhost:8080/camel/demo
@Component
public class TestRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
onException(Throwable.class)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("exception caught!!");
}
}).handled(true);
rest("/")
.consumes("application/ json;charset=UTF-8")
.produces("application/ json;charset=UTF-8")
.get("/demo")
.to("direct:next-step");
from("direct:next-step")
.doTry()
// invoking SOAP service
.process(exchange -> {
throw new RuntimeException("Random Exception");
})
.doCatch(Throwable.class)
.process(exchange -> {
throw new IllegalStateException("not in a valid state");
});
}
}
My build.gradle file below :
buildscript {
ext {
camelSpringVersion = '4.4.5' // this works as expected
//camelSpringVersion = '4.10.2' // this is broken
}
}
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation "org.apache.camel:camel-http:${camelSpringVersion}"
implementation "org.apache.camel.springboot:camel-spring-boot-starter:${camelSpringVersion}"
implementation "org.apache.camel.springboot:camel-servlet-starter:${camelSpringVersion}"
implementation "org.apache.camel.springboot:camel-jackson-starter:${camelSpringVersion}"
implementation "org.apache.camel:camel-health:${camelSpringVersion}"
}
tasks.named('test') {
useJUnitPlatform()
}
Solution 1 ::
In order to preserve existing behaviour, you need to set this property
camel.rest.inline-routes = false
in all versions post 4.7.x.
Solution 2 ::
If you add a dummy route, its working as expected. For example if you modify above code as below, its working as expected.
@Component
public class TestRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
onException(Throwable.class)
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("exception caught!!");
}
}).handled(true);
rest("/")
.consumes("application/ json;charset=UTF-8")
.produces("application/ json;charset=UTF-8")
.get("/demo")
.to("direct:next-step-dummy");
from("direct:next-step-dummy") // setting a dummy route
.to("direct:next-step");
from("direct:next-step")
.doTry()
// invoking SOAP service
.process(exchange -> {
throw new RuntimeException("Random Exception");
})
.doCatch(Throwable.class)
.process(exchange -> {
throw new IllegalStateException("not in a valid state");
});
}
}