src/main/java/com/arpnetworking/logback/serialization/steno/StenoSerializationHelper.java
public static void serializeThrowable(
            final IThrowableProxy throwableProxy,
            final JsonGenerator jsonGenerator,
            final ObjectMapper objectMapper)
            throws IOException {

        jsonGenerator.writeStringField("type", throwableProxy.getClassName());
        jsonGenerator.writeStringField("message", throwableProxy.getMessage());
        jsonGenerator.writeArrayFieldStart("backtrace");
        for (final StackTraceElementProxy ste : throwableProxy.getStackTraceElementProxyArray()) {
            jsonGenerator.writeString(ste.toString());
        }
        jsonGenerator.writeEndArray();
        jsonGenerator.writeObjectFieldStart("data");
        if (throwableProxy instanceof ThrowableProxy) {
            final JsonNode jsonNode = objectMapper.valueToTree(((ThrowableProxy) throwableProxy).getThrowable());
            for (final Iterator<Map.Entry<String, JsonNode>> iterator = jsonNode.fields(); iterator.hasNext();) {
                final Map.Entry<String, JsonNode> field = iterator.next();
                jsonGenerator.writeFieldName(field.getKey());
                objectMapper.writeValue(
                        jsonGenerator,
                        field.getValue());
            }
        }
        // Although Throwable has a final getSuppressed which cannot return a null array, the
        // proxy in Logback provides no such guarantees.
        if (throwableProxy.getSuppressed() != null && throwableProxy.getSuppressed().length > 0) {
            jsonGenerator.writeArrayFieldStart("suppressed");
            for (final IThrowableProxy suppressed : throwableProxy.getSuppressed()) {
                jsonGenerator.writeStartObject();
                serializeThrowable(suppressed, jsonGenerator, objectMapper);
                jsonGenerator.writeEndObject();
            }
            jsonGenerator.writeEndArray();
        }
        if (throwableProxy.getCause() != null) {
            jsonGenerator.writeObjectFieldStart("cause");
            serializeThrowable(throwableProxy.getCause(), jsonGenerator, objectMapper);
            jsonGenerator.writeEndObject();
        }
        jsonGenerator.writeEndObject();
    }
public static void serializeThrowable(
            final IThrowableProxy throwableProxy,
            final JsonGenerator jsonGenerator,
            final ObjectMapper objectMapper)
            throws IOException {

        jsonGenerator.writeStringField("type", throwableProxy.getClassName());
        jsonGenerator.writeStringField("message", throwableProxy.getMessage());
        jsonGenerator.writeArrayFieldStart("backtrace");
        for (final StackTraceElementProxy ste : throwableProxy.getStackTraceElementProxyArray()) {
            jsonGenerator.writeString(ste.toString());
        }
        jsonGenerator.writeEndArray();
        jsonGenerator.writeObjectFieldStart("data");
        if (throwableProxy instanceof ThrowableProxy) {
            final JsonNode jsonNode = objectMapper.valueToTree(((ThrowableProxy) throwableProxy).getThrowable());
            for (final Iterator<Map.Entry<String, JsonNode>> iterator = jsonNode.fields(); iterator.hasNext();) {
                final Map.Entry<String, JsonNode> field = iterator.next();
                jsonGenerator.writeFieldName(field.getKey());
                objectMapper.writeValue(
                        jsonGenerator,
                        field.getValue());
            }
        }
        // Although Throwable has a final getSuppressed which cannot return a null array, the
        // proxy in Logback provides no such guarantees.
        if (throwableProxy.getSuppressed() != null && throwableProxy.getSuppressed().length > 0) {
            jsonGenerator.writeArrayFieldStart("suppressed");
            for (final IThrowableProxy suppressed : throwableProxy.getSuppressed()) {
                jsonGenerator.writeStartObject();
                serializeThrowable(suppressed, jsonGenerator, objectMapper);
                jsonGenerator.writeEndObject();
            }
            jsonGenerator.writeEndArray();
        }
        if (throwableProxy.getCause() != null) {
            jsonGenerator.writeObjectFieldStart("cause");
            serializeThrowable(throwableProxy.getCause(), jsonGenerator, objectMapper);
            jsonGenerator.writeEndObject();
        }
        jsonGenerator.writeEndObject();
    }
This function assumes the field object has already been started for this throwable, this only fills in
the fields in the 'exception' or equivalent object and does not create the field in the containing object.

@since 1.7.0
@param throwableProxy Throwable to serialize
@param jsonGenerator  <code>JsonGenerator</code> instance after exception object is started
@param objectMapper <code>ObjectMapper</code> instance.
@throws IOException If writing the <code>Throwable</code> as JSON fails.