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)

Reply via email to