Skip to content

Commit

Permalink
Do not try to end structure in encode/decode stucture extensions if a…
Browse files Browse the repository at this point in the history
…n exception has been thrown, so the original exception will be propagated

Fixes #1187
  • Loading branch information
qwwdfsad committed Nov 13, 2020
1 parent 31f646a commit f0fd3a4
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
package kotlinx.serialization.encoding

import kotlinx.serialization.*
import kotlinx.serialization.builtins.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.modules.*
import kotlinx.serialization.builtins.*

/**
* Decoder is a core deserialization primitive that encapsulates the knowledge of the underlying
Expand Down Expand Up @@ -524,10 +524,15 @@ public inline fun <T> Decoder.decodeStructure(
block: CompositeDecoder.() -> T
): T {
val composite = beginStructure(descriptor)
var ex: Throwable? = null
try {
return composite.block()
} catch (e: Throwable) {
ex = e
throw e
} finally {
composite.endStructure(descriptor)
// End structure only if there is no exception, otherwise it can be swallowed
if (ex == null) composite.endStructure(descriptor)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,14 @@ public interface CompositeEncoder {
*/
public inline fun Encoder.encodeStructure(descriptor: SerialDescriptor, block: CompositeEncoder.() -> Unit) {
val composite = beginStructure(descriptor)
var ex: Throwable? = null
try {
composite.block()
} catch (e: Throwable) {
ex = e
throw e
} finally {
composite.endStructure(descriptor)
// End structure only if there is no exception, otherwise it can be swallowed
if (ex == null) composite.endStructure(descriptor)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package kotlinx.serialization

import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.json.*
import kotlin.test.*

class EncodingExtensionsTest {

@Serializable(with = BoxSerializer::class)
class Box(val i: Int)

@Serializer(forClass = Box::class)
object BoxSerializer : KSerializer<Box> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Box") {
element<Int>("i")
}

override fun serialize(encoder: Encoder, value: Box) {
encoder.encodeStructure(descriptor) {
throw ArithmeticException()
}
}

override fun deserialize(decoder: Decoder): Box {
decoder.decodeStructure(descriptor) {
throw ArithmeticException()
}
}
}

@Test
fun testEncodingExceptionNotSwallowed() {
assertFailsWith<ArithmeticException> { Json.encodeToString(Box(1)) }
}

@Test
fun testDecodingExceptionNotSwallowed() {
assertFailsWith<ArithmeticException> { Json.decodeFromString<Box>("""{"i":1}""") }
}
}

0 comments on commit f0fd3a4

Please sign in to comment.