1414import io .opentelemetry .sdk .trace .data .ExceptionEventData ;
1515import java .io .PrintWriter ;
1616import java .io .StringWriter ;
17+ import javax .annotation .Nullable ;
1718import javax .annotation .concurrent .Immutable ;
1819
1920/**
@@ -40,18 +41,27 @@ public final String getName() {
4041 return EXCEPTION_EVENT_NAME ;
4142 }
4243
43- /** TODO. */
44+ // Autowire generates AutoValue_LazyExceptionEventData and $AutoValue_LazyExceptionEventData to
45+ // account to memoize getAttributes. Unfortunately, $AutoValue_LazyExceptionEventData's
46+ // exceptionMessage constructor param is properly annotated with @Nullable, but
47+ // AutoValue_LazyExceptionEventData's is not. So we suppress the NullAway false positive.
48+ @ SuppressWarnings ("NullAway" )
4449 public static ExceptionEventData create (
4550 long epochNanos ,
4651 Throwable exception ,
4752 Attributes additionalAttributes ,
4853 SpanLimits spanLimits ) {
54+ // Compute exception message at initialization time to be conservative about possibility of
55+ // Exception#geMessage() not being thread safe
4956 return new AutoValue_LazyExceptionEventData (
50- epochNanos , exception , spanLimits , additionalAttributes );
57+ epochNanos , exception , spanLimits , exception . getMessage (), additionalAttributes );
5158 }
5259
5360 abstract SpanLimits getSpanLimits ();
5461
62+ @ Nullable
63+ abstract String getExceptionMessage ();
64+
5565 public abstract Attributes getAdditionalAttributes ();
5666
5767 @ Override
@@ -65,7 +75,7 @@ public Attributes getAttributes() {
6575 AttributesMap .create (
6676 spanLimits .getMaxNumberOfAttributes (), spanLimits .getMaxAttributeValueLength ());
6777 String exceptionName = exception .getClass ().getCanonicalName ();
68- String exceptionMessage = exception . getMessage ();
78+ String exceptionMessage = getExceptionMessage ();
6979 StringWriter stringWriter = new StringWriter ();
7080 try (PrintWriter printWriter = new PrintWriter (stringWriter )) {
7181 exception .printStackTrace (printWriter );
0 commit comments