Andrea Cosentino created CAMEL-24251:
----------------------------------------
Summary: camel-aws2 producer health checks can throw NPE when
AwsServiceException has no error details
Key: CAMEL-24251
URL: https://issues.apache.org/jira/browse/CAMEL-24251
Project: Camel
Issue Type: Bug
Components: camel-aws
Reporter: Andrea Cosentino
h3. Problem
Every AWS v2 producer health check catches {{AwsServiceException}} and records
two details -- the HTTP status code and the AWS error code. The status code is
guarded for null, but {{awsErrorDetails()}} is dereferenced directly:
{code:java}
} catch (AwsServiceException e) {
builder.message(e.getMessage());
builder.error(e);
if (ObjectHelper.isNotEmpty(e.statusCode())) { // guarded
builder.detail(SERVICE_STATUS_CODE, e.statusCode());
}
if (ObjectHelper.isNotEmpty(e.awsErrorDetails().errorCode())) { //
e.awsErrorDetails() dereferenced unguarded
builder.detail(SERVICE_ERROR_CODE, e.awsErrorDetails().errorCode());
}
builder.down();
return;
}
{code}
{{AwsServiceException.awsErrorDetails()}} is nullable (it is a plain builder
field that defaults to null and is only populated when the SDK successfully
unmarshals a structured error response). When an {{AwsServiceException}}
reaches this block with {{awsErrorDetails() == null}} -- for example a 5xx
whose body the SDK could not parse into an error, or an exception synthesized
on an internal error path -- {{e.awsErrorDetails().errorCode()}} throws
{{NullPointerException}}.
The consequence is that the health check itself blows up with an NPE instead of
reporting the endpoint as {{DOWN}} with the message it had already prepared: a
genuine "service unreachable" signal is turned into a health-check framework
error.
The inconsistency is the tell: the author guarded {{statusCode()}} one line
above but not {{awsErrorDetails()}}.
h3. Scope
The same copy-pasted block appears in 21 producer health checks: athena,
comprehend, cw, ddb, ec2, ecs, eks, eventbridge, lambda, mq, polly,
rekognition, step-functions, textract, timestream (query + write), translate,
config, parameter-store, secrets-manager and security-hub.
{{Textract2ProducerHealthCheck}} additionally dereferences
{{e.awsErrorDetails().errorCode()}} in an {{equals(...)}} test that classifies
certain errors as healthy, so it has two unguarded sites.
h3. Proposed fix
Guard {{awsErrorDetails()}} for null before dereferencing it, consistently with
the neighbouring {{statusCode()}} guard.
h3. Affected versions
The block is present on {{main}}; the subset of these components that exists on
{{camel-4.18.x}} and {{camel-4.14.x}} carries it verbatim (verified per module
during backport).
----
_Reported by Claude Code on behalf of acosentino, from an automated audit of
the camel-aws components._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)