Alexander Zobkov created CAMEL-24380:
----------------------------------------
Summary: Regression in platform-http/platform-http-starter timeout
handling
Key: CAMEL-24380
URL: https://issues.apache.org/jira/browse/CAMEL-24380
Project: Camel
Issue Type: Bug
Components: camel-platform-http
Affects Versions: 4.18.3
Reporter: Alexander Zobkov
After upgrading camel and camel-spring-boot from 4.17.0 to 4.18.3, we observed
a regression in how request timeouts are handled on camel-platform-http routes.
Route:
from(EndpointBuilder.instance.platformHttp('/path/a/b/c')
.httpMethodRestrict('GET'))
...
.to(call-to-legacy-system)
...
The downstream legacy-system is occasionally slow, and its response time can
exceed the value configured in camel.component.platform-http.request-timeout.
Behavior in 4.17.0:
When the timeout is reached, Spring Boot's default error handling produces a
well-formed JSON response:
{"timestamp":"2026-08-05T20:12:09.500+00:00","status":503,"error":"Service
Unavailable","path":"/path/a/b/c"}
Behavior in 4.18.3:
The same scenario now returns the Whitelabel Error Page as HTML, with a null
status and type:
<html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit
mapping for /error, so you are seeing this as a fallback.</p><div
id='created'>null</div><div>There was an unexpected error (type=null,
status=null).</div></body></html>
Suspected root cause:
I bisected the change to commit d8e1581 ("chore: use WebAsyncTask, fix
@LocalServerPort, revert generated file"), which changed
SpringBootPlatformHttpConsumer#service() from returning a plain Callable<Void>
to a WebAsyncTask<Void> with a custom onTimeout handler:
java
task.onTimeout(() -> {
if (!response.isCommitted()) {
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
}
return null;
});
In 4.17.0, an unhandled timeout produced an AsyncRequestTimeoutException, which
Spring MVC's ResponseStatusExceptionResolver translates into a 503 dispatch to
/error, correctly populating the jakarta.servlet.error.* request attributes
that BasicErrorController/DefaultErrorAttributes rely on to render the JSON
body.
In 4.18.3, response.sendError(503) is now called directly inside the onTimeout
callback, and the callback returns null as the async result. No exception is
ever raised through Spring's exception-resolution chain, so when the container
performs the subsequent error dispatch to /error, the expected request
attributes are missing — resulting in the generic Whitelabel page with
status=null, type=null instead of Boot's normal structured error response.
Expected behavior:
A platform-http timeout should still result in Spring Boot's standard /error
handling (JSON body with correct status/error/path), consistent with the
pre-4.18.3 behavior.
Suggested fix direction:
Rather than calling response.sendError() directly in onTimeout, either let an
AsyncRequestTimeoutException (or equivalent) propagate so Spring's normal
exception-resolution/error-dispatch machinery populates the error attributes,
or explicitly set the jakarta.servlet.error.* request attributes before
triggering the error dispatch.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)