-
Notifications
You must be signed in to change notification settings - Fork 618
/
SerializationException.kt
74 lines (66 loc) · 3.22 KB
/
SerializationException.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.serialization
/**
* A generic exception indicating the problem in serialization or deserialization process.
* This is a generic exception type that can be thrown during the problem at any stage of the serialization,
* including encoding, decoding, serialization, deserialization.
* [SerialFormat] implementors should throw subclasses of this exception at any unexpected event,
* whether it is a malformed input or unsupported class layout.
*/
public open class SerializationException : IllegalArgumentException {
/*
* Rationale behind making it IllegalArgumentException:
* Any serialization exception is triggered by the illegal argument, whether
* it is a serializer that does not support specific structure or an invalid input.
* Making it IAE just aligns the implementation with this fact.
*
* Another point is input validation. The simplest way to validate
* deserialized data is `require` in `init` block:
* ```
* @Serializable class Foo(...) {
* init {
* required(age > 0) { ... }
* require(name.isNotBlank()) { ... }
* }
* }
* ```
* While clearly being serialization error (when compromised data was deserialized),
* Kotlin way is to throw IAE here instead of using library-specific SerializationException.
*
* Also, any production-grade system has a general try-catch around deserialization of potentially
* untrusted/invalid/corrupted data with the corresponding logging, error reporting and diagnostic.
* Such handling should catch some subtype of exception (e.g. it's unlikely that catching OOM is desirable).
* Taking it into account, it becomes clear that SE should be subtype of IAE.
*/
/**
* Creates an instance of [SerializationException] without any details.
*/
public constructor()
/**
* Creates an instance of [SerializationException] with the specified detail [message].
*/
public constructor(message: String?) : super(message)
/**
* Creates an instance of [SerializationException] with the specified detail [message], and the given [cause].
*/
public constructor(message: String?, cause: Throwable?) : super(message, cause)
/**
* Creates an instance of [SerializationException] with the specified [cause].
*/
public constructor(cause: Throwable?) : super(cause)
}
/**
* Thrown when [KSerializer] did not receive property from [Decoder], and this property was not optional.
*/
@PublishedApi
internal class MissingFieldException(fieldName: String) : // TODO: add (message, cause) ctor after 1.4.20 for coroutines stacktrace recovery
SerializationException("Field '$fieldName' is required, but it was missing")
/**
* Thrown when [KSerializer] received unknown property index from [CompositeDecoder.decodeElementIndex].
*
* This exception means that data schema has changed in backwards-incompatible way.
*/
@PublishedApi // TODO: add (message, cause) ctor after 1.4.20 for coroutines stacktrace recovery
internal class UnknownFieldException(index: Int) : SerializationException("An unknown field for index $index")