in aws-xray-recorder-sdk-core/src/main/java/com/amazonaws/xray/strategy/DefaultThrowableSerializationStrategy.java [119:182]
public List<ThrowableDescription> describeInContext(
@Nullable Entity entity,
Throwable throwable,
List<Subsegment> subsegments
) {
List<ThrowableDescription> result = new ArrayList<>();
IdGenerator idGenerator;
// We could fall back on ThreadLocalStorage#get if we were confident that no `SegmentContext` implementations
// override the default get/setTraceEntity implementations, but we can't make that guarantee.
if (entity != null) {
idGenerator = entity.getCreator().getIdGenerator();
} else if (!subsegments.isEmpty()) {
idGenerator = subsegments.get(0).getCreator().getIdGenerator();
} else {
idGenerator = AWSXRay.getGlobalRecorder().getIdGenerator();
}
/*
* Visit each node in the cause chain. For each node:
* Determine if it has already been described in one of the child subsegments' causes. If so, link there.
* Otherwise, describe it and add it to the result.
*/
ThrowableDescription description = new ThrowableDescription();
Optional<ThrowableDescription> exceptionReferenced = referenceInChildren(throwable, subsegments);
if (exceptionReferenced.isPresent()) {
//already described, we can link to this one by ID. Get the id from the child's Throwabledescription (if it has one).
//Use the cause otherwise.
ThrowableDescription exception = exceptionReferenced.get();
description.setCause(exception.getId() != null ? exception.getId() : exception.getCause());
description.setThrowable(throwable);
result.add(description);
return result;
} else {
description = describeThrowable(throwable, idGenerator.newEntityId());
result.add(description);
}
Throwable nextNode = throwable.getCause();
while (null != nextNode) {
final Throwable currentNode = nextNode;
exceptionReferenced = referenceInChildren(currentNode, subsegments);
if (exceptionReferenced.isPresent()) {
description.setCause(null == exceptionReferenced.get().getId() ?
exceptionReferenced.get().getCause() : exceptionReferenced.get().getId());
} else {
//Link it, and start a new description
String newId = idGenerator.newEntityId();
description.setCause(newId);
description = describeThrowable(currentNode, newId);
}
result.add(description);
nextNode = nextNode.getCause();
}
return result;
}