CAMEL-24404: camel-base-engine: wrap consumer startup exceptions in FailedToStartRouteException in InternalRouteStartupManager - #25554
Conversation
…outeException in InternalRouteStartupManager
Before this fix the two catch blocks in doStartOrResumeRouteConsumers()
re-threw the raw exception with a bare 'throw e'. When the consumer's
start() threw a message-less exception (e.g. NullPointerException from
FileConsumer.doStart), the NPE escaped directly to callers instead of
being wrapped in FailedToStartRouteException.
Real-world stack trace:
java.lang.NullPointerException
at o.a.c.component.file.FileConsumer.doStart(FileConsumer.java:123)
at o.a.c.support.service.BaseService.start(BaseService.java:119)
at o.a.c.support.service.ServiceHelper.startService(ServiceHelper.java:113)
at o.a.c.impl.engine.InternalRouteStartupManager
.doStartOrResumeRouteConsumers(InternalRouteStartupManager.java:429)
Fix: replace both bare 'throw e' sites with:
throw new FailedToStartRouteException(
routeService.getId(), routeService.getLocation(),
extractUsefulMessage(e), e);
Add extractUsefulMessage() helper (same pattern already used in
RouteService fixed in PR apache#25205) that walks the cause chain for a
non-null message and falls back to the simple class name.
Add InternalRouteStartupManagerConsumerStartTest with two tests:
- bare NPE produces FailedToStartRouteException with non-null message
- chained exception surfaces the cause message
Co-authored-by: Claude <claude@anthropic.com>
JIRA Issue: CAMEL-24404Link: https://issues.apache.org/jira/browse/CAMEL-24404 ProblemTwo catch blocks in re-throw the consumer startup exception raw with bare . When a consumer throws a message-less exception (e.g. bare ), the NPE escapes directly to callers instead of being wrapped in . Stack TraceNoteand have the same null-message problem and are fixed separately in PR #25205. |
…l after InternalRouteStartupManager change
After wrapping raw consumer startup exceptions in FailedToStartRouteException,
two tests that asserted on the raw IllegalArgumentException type/message broke:
- MainSupervisingRouteControllerTest (testMain, testMainApplicationProperties):
assertInstanceOf(IllegalArgumentException.class, e) -> now asserts
FailedToStartRouteException with IllegalArgumentException as cause
- SpringSupervisingRouteControllerTest (testSupervising):
assertTrue(e instanceof IllegalArgumentException) -> now asserts
FailedToStartRouteException with IllegalArgumentException as cause
Both tests now assert:
assertInstanceOf(FailedToStartRouteException.class, e)
assertInstanceOf(IllegalArgumentException.class, e.getCause())
assertEquals("Cannot start", e.getCause().getMessage())
Local validation:
- mvn formatter:format impsort:sort (3 modules) -- no changes needed
- InternalRouteStartupManagerConsumerStartTest: run 2, Failures 0
- MainSupervisingRouteControllerTest: run 3, Failures 0
- SpringSupervisingRouteControllerTest: run 1, Failures 0
Co-authored-by: Claude <claude@anthropic.com>
Addressed: broken tests in camel-main and camel-spring-xmlFixed the two test files flagged in the review of PR #25205:
Before: assertEquals("Cannot start", e.getMessage());
assertInstanceOf(IllegalArgumentException.class, e);After: assertInstanceOf(FailedToStartRouteException.class, e);
assertInstanceOf(IllegalArgumentException.class, e.getCause());
assertEquals("Cannot start", e.getCause().getMessage());
Before: assertEquals("Cannot start", e.getMessage());
assertTrue(e instanceof IllegalArgumentException);After: assertTrue(e instanceof FailedToStartRouteException);
assertTrue(e.getCause() instanceof IllegalArgumentException);
assertEquals("Cannot start", e.getCause().getMessage());Local validation (all passing):
[JDK 21 / Maven 3.9] |
Summary
Fixes CAMEL-24404.
The two bare
throw esites inInternalRouteStartupManager.doStartOrResumeRouteConsumers()re-threw consumer startup exceptions raw instead of wrapping them inFailedToStartRouteException.JIRA
CAMEL-24404 — camel-base-engine: InternalRouteStartupManager re-throws consumer startup exceptions raw instead of wrapping in FailedToStartRouteException
Root Cause
When a consumer
sstart()throws a message-less exception (e.g. a bareNullPointerExceptionfromFileConsumer.doStart()), the two catch blocks at lines 427-432 and 465-470 re-threw it raw withthrow e. Callers received an unwrapped NPE instead of aFailedToStartRouteException`.Real-world stack trace:
Note:
RouteService.warmUp()andRouteService.setUp()have the same null-message problem and are fixed separately in PR #25205.Fix
Replace both
throw esites with:Add
extractUsefulMessage()helper (same pattern as PR #25205) that walks the cause chain for a non-null message and falls back to the simple class name.Changes
core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalRouteStartupManager.java— replace boththrow esites; addextractUsefulMessage()helpercore/camel-core/src/test/java/org/apache/camel/impl/engine/InternalRouteStartupManagerConsumerStartTest.java(new) — 2 testsTest Results
AI Attribution
This contribution was developed with AI assistance using Claude Code.