in src/main/java/com/uber/cadence/converter/CustomThrowableTypeAdapter.java [62:127]
public void write(JsonWriter jsonWriter, T throwable) throws IOException {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
StackTraceElement[] trace = throwable.getStackTrace();
for (StackTraceElement element : trace) {
pw.println(element);
String fullMethodName = element.getClassName() + "." + element.getMethodName();
if (CUTOFF_METHOD_NAMES.contains(fullMethodName)) {
break;
}
}
// We want to serialize the throwable and its cause separately, so that if the throwable
// is serializable but the cause is not, we can still serialize them correctly (i.e. we
// serialize the throwable correctly and convert the cause to a data converter exception).
Throwable cause = null;
if (throwable.getCause() != null && throwable.getCause() != throwable) {
try {
cause = throwable.getCause();
Field causeField = Throwable.class.getDeclaredField("cause");
causeField.setAccessible(true);
causeField.set(throwable, null);
} catch (Exception e) {
log.warn("Failed to clear cause in original throwable.", e);
}
}
JsonObject object;
try {
TypeAdapter exceptionTypeAdapter =
gson.getDelegateAdapter(skipPast, TypeToken.get(throwable.getClass()));
object = exceptionTypeAdapter.toJsonTree(throwable).getAsJsonObject();
object.add("class", new JsonPrimitive(throwable.getClass().getName()));
object.add("stackTrace", new JsonPrimitive(sw.toString()));
} catch (Throwable e) {
// In case a throwable is not serializable, we will convert it to a data converter exception.
// The cause of the data converter exception will indicate why the serialization failed. On
// the other hand, if the non-serializable throwable contains a cause, we will add it to the
// suppressed exceptions list.
DataConverterException ee =
new DataConverterException("Failure serializing exception: " + throwable.toString(), e);
if (cause != null) {
ee.addSuppressed(cause);
cause = null;
}
TypeAdapter<Throwable> exceptionTypeAdapter =
new CustomThrowableTypeAdapter<>(gson, skipPast);
object = exceptionTypeAdapter.toJsonTree(ee).getAsJsonObject();
}
if (cause != null) {
TypeAdapter<Throwable> causeTypeAdapter = new CustomThrowableTypeAdapter<>(gson, skipPast);
try {
object.add("cause", causeTypeAdapter.toJsonTree(cause));
} catch (Throwable e) {
DataConverterException ee =
new DataConverterException("Failure serializing exception: " + cause.toString(), e);
ee.setStackTrace(cause.getStackTrace());
object.add("cause", causeTypeAdapter.toJsonTree(ee));
}
}
TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
elementAdapter.write(jsonWriter, object);
}