rocketraman
02/10/2022, 2:10 PMServiceException
open so that the client can act based on sub-classes of it?Robert Jaros
02/10/2022, 2:21 PMrocketraman
02/10/2022, 2:25 PMRobert Jaros
02/10/2022, 2:28 PMrocketraman
02/10/2022, 2:30 PMserializer()
on it though if its just a generic type.Robert Jaros
02/10/2022, 3:29 PMrocketraman
02/10/2022, 3:31 PMRobert Jaros
02/10/2022, 3:31 PMrocketraman
02/10/2022, 3:32 PMRobert Jaros
02/10/2022, 3:32 PM@Serializable
abstract class MyException(val msg: String): Exception(msg)
@Serializable
@SerialName("mysecond")
class MySecondException : MyException("MySecond")
val json = Json {
serializersModule = SerializersModule {
polymorphic(MyException::class) {
subclass(MySecondException::class)
}
}
}
val e: MyException = MySecondException()
val serialized = json.encodeToString(e)
console.log(serialized)
val deserialized = json.decodeFromString<MyException>(serialized)
try {
throw deserialized
} catch (e: MySecondException) {
console.log("Cought: ${e.msg}")
}
rocketraman
02/10/2022, 3:32 PMSerialization can work with arbitrary open classes or abstract classes.
Robert Jaros
02/10/2022, 3:33 PMe.msg
but e.message
property is undefined
RemoteSerialization.customConfiguration
option I've added recently.rocketraman
02/10/2022, 3:46 PMServiceRpcException
instead of ServiceException
, and the frontend does RpcError(e)
to unwrap the RpcError
instance.
@Serializable
sealed class RpcError {
companion object {
// used by the frontend e.g. RpcError(e) where e is a ServiceException
operator fun invoke(serviceException: ServiceException) =
Json.decodeFromString<RpcError>(serviceException.message!!)
}
@Serializable
object Unauthorized : RpcError()
// ... as many types as needed ...
@Serializable
class UnexpectedError(val errorId: String) : RpcError()
}
object ServiceRpcException {
// used by the backend e.g. ServiceRpcException(RpcError.Unauthorized)
operator fun invoke(rpcError: RpcError): ServiceException =
ServiceException(Json.encodeToString(rpcError))
}