Nullability issue with TextChannel.createMessage and EmbedBuilder.Author
Loatchi opened this issue · comments
When working on a bot of mine I to be able to create message from a text channel 's id.
However I found out that when creating and embed with an author field you must mention both the name and the url otherwise the deserializer will stop on a null value.
val myGuildSnowflake: Snowflake
val myTextChannelSnowflake: Snowflake
(kord.getGuildOrThrow(myGuildSnowflake)
.getChannel(myTextChannelSnowflake) as TextChannel)
.createMessage {
embed {
description = "foo"
author {
name = "bar"
}
}
}
would cause:
Exception in thread "main" kotlinx.serialization.SerializationException: descriptor for kotlin.String was not nullable but null mark was encountered
at dev.kord.common.entity.optional.Optional$OptionalSerializer.deserialize(Optional.kt:164)
at dev.kord.common.entity.optional.Optional$OptionalSerializer.deserialize(Optional.kt:155)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:165)
at dev.kord.common.entity.DiscordEmbed$Author$$serializer.deserialize(DiscordMessage.kt:670)
at dev.kord.common.entity.DiscordEmbed$Author$$serializer.deserialize(DiscordMessage.kt:670)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
at dev.kord.common.entity.optional.Optional$OptionalSerializer.deserialize(Optional.kt:177)
at dev.kord.common.entity.optional.Optional$OptionalSerializer.deserialize(Optional.kt:155)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:165)
at dev.kord.common.entity.DiscordEmbed$$serializer.deserialize(DiscordMessage.kt:569)
at dev.kord.common.entity.DiscordEmbed$$serializer.deserialize(DiscordMessage.kt:569)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:165)
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:533)
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80)
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:165)
at dev.kord.common.entity.DiscordMessage$$serializer.deserialize(DiscordMessage.kt:164)
at dev.kord.common.entity.DiscordMessage$$serializer.deserialize(DiscordMessage.kt:164)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:70)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107)
at dev.kord.rest.route.ValueJsonMapper.deserialize(Route.kt:24)
at dev.kord.rest.request.KtorRequestHandler.handle(KtorRequestHandler.kt:68)
at dev.kord.rest.request.KtorRequestHandler$handle$1.invokeSuspend(KtorRequestHandler.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:177)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:508)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:497)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:368)
at kotlinx.coroutines.ResumeOnCompletion.invoke(JobSupport.kt:1390)
at kotlinx.coroutines.JobSupport.notifyCompletion(JobSupport.kt:1494)
at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:324)
at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:241)
at kotlinx.coroutines.JobSupport.continueCompleting(JobSupport.kt:938)
at kotlinx.coroutines.JobSupport.access$continueCompleting(JobSupport.kt:25)
at kotlinx.coroutines.JobSupport$ChildCompletion.invoke(JobSupport.kt:1158)
at kotlinx.coroutines.JobSupport.notifyCompletion(JobSupport.kt:1494)
at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:324)
at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:241)
at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:909)
at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:866)
at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:831)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:100)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
However simply adding:
author {
name = "bar"
url = "https://github.com/kordlib/kord" // any link here
}
would work.
It is similar to this already closed issue.
However it's for the url field in author's embed.
So it should be fixable by simply allowing null value here.
This looks like a documentation error on Discord side, since all fields are not nullable here, could you turn on TRACE LOGGING and share the exact JSON coming back?
There you go, this is the Json that came back when sending a message this way.
{
"id": "1121768099201421412",
"type": 0,
"content": "",
"channel_id": "xxxx",
"author": {
...
},
"attachments": [],
"embeds": [
{
"type": "rich",
"description": "foo",
"author": {
"name": "bar",
"url": null
}
}
],
"mentions": [],
"mention_roles": [],
"pinned": false,
"mention_everyone": false,
"tts": false,
"timestamp": "2023-06-23T11:45:56.293000+00:00",
"edited_timestamp": null,
"flags": 0,
"components": [],
"referenced_message": null
}
I've truncated author and channel but they are looking fine and indeed the url part is null instead of missing.
i think we should just change the type of DiscordEmbed.Author.url
to Optional<String?>
, should work then
might want to send this to the @discord repo?
Ok sorry for the long response time I had to fight against gradle pulling the 0.9.0 dep.
Running the same command as I started with does indeed work @lukellmann.
I'll open a ticket on the discord api docs.
0.10.0-SNAPSHOT
should now also contain the fix