@@ -16,7 +16,6 @@ import java.io.InputStream
1616import java.io.ObjectInputStream
1717import java.io.ObjectOutputStream
1818import java.io.ObjectStreamClass
19- import java.lang.RuntimeException
2019
2120class ThrowableSerializer : Serializer <Throwable >() {
2221 companion object {
@@ -29,7 +28,7 @@ class ThrowableSerializer : Serializer<Throwable>() {
2928 val message : String? ,
3029 val stackTrace : Array <StackTraceElement >,
3130 val cause : ThrowableModel ? ,
32- val serializedException : ByteArray ,
31+ val serializedExceptionBytes : ByteArray? ,
3332 )
3433
3534 override fun write (kryo : Kryo , output : Output , throwable : Throwable ? ) {
@@ -38,33 +37,44 @@ class ThrowableSerializer : Serializer<Throwable>() {
3837 message = message,
3938 stackTrace = stackTrace,
4039 cause = cause?.toModel(),
41- serializedException = ByteArrayOutputStream ().use { byteOutputStream ->
42- val objectOutputStream = ObjectOutputStream (byteOutputStream)
43- objectOutputStream.writeObject(this )
44- objectOutputStream.flush()
45- byteOutputStream.toByteArray()
40+ serializedExceptionBytes = try {
41+ ByteArrayOutputStream ().use { byteOutputStream ->
42+ val objectOutputStream = ObjectOutputStream (byteOutputStream)
43+ objectOutputStream.writeObject(this )
44+ objectOutputStream.flush()
45+ byteOutputStream.toByteArray()
46+ }
47+ } catch (e: Throwable ) {
48+ if (loggedUnserializableExceptionClassIds.add(this ::class .java.id)) {
49+ logger.warn { " Failed to serialize ${this ::class .java.id} to bytes, cause: $e " }
50+ logger.warn { " Constructing ThrowableModel with serializedExceptionBytes = null" }
51+ }
52+ null
4653 }
4754 )
4855 kryo.writeObject(output, throwable?.toModel())
4956 }
5057
5158 override fun read (kryo : Kryo , input : Input , type : Class <out Throwable >): Throwable ? {
52- fun ThrowableModel.toThrowable (): Throwable = try {
53- ByteArrayInputStream (this .serializedException).use { byteInputStream ->
54- val objectInputStream = IgnoringUidWrappingObjectInputStream (byteInputStream, kryo.classLoader)
55- objectInputStream.readObject() as Throwable
56- }
57- } catch (e: Throwable ) {
58- if (loggedUnserializableExceptionClassIds.add(this .classId)) {
59- logger.warn { " Failed to deserialize ${this .classId} from bytes, cause: $e " }
60- logger.warn { " Falling back to constructing throwable instance from ThrowableModel" }
59+ fun ThrowableModel.toThrowable (): Throwable {
60+ val throwableFromBytes = this .serializedExceptionBytes?.let { bytes ->
61+ try {
62+ ByteArrayInputStream (bytes).use { byteInputStream ->
63+ val objectInputStream = IgnoringUidWrappingObjectInputStream (byteInputStream, kryo.classLoader)
64+ objectInputStream.readObject() as Throwable
65+ }
66+ } catch (e: Throwable ) {
67+ if (loggedUnserializableExceptionClassIds.add(this .classId)) {
68+ logger.warn { " Failed to deserialize ${this .classId} from bytes, cause: $e " }
69+ logger.warn { " Falling back to constructing throwable instance from ThrowableModel" }
70+ }
71+ null
72+ }
6173 }
62-
63- val cause = cause?.toThrowable()
64- when {
65- RuntimeException ::class .java.isAssignableFrom(classId.jClass) -> RuntimeException (message, cause)
66- Error ::class .java.isAssignableFrom(classId.jClass) -> Error (message, cause)
67- else -> Exception (message, cause)
74+ return throwableFromBytes ? : when {
75+ RuntimeException ::class .java.isAssignableFrom(classId.jClass) -> RuntimeException (message, cause?.toThrowable())
76+ Error ::class .java.isAssignableFrom(classId.jClass) -> Error (message, cause?.toThrowable())
77+ else -> Exception (message, cause?.toThrowable())
6878 }.also {
6979 it.stackTrace = stackTrace
7080 }
0 commit comments