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)

Reply via email to