Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing of a custom MetadataKey leads to an exception #70

Open
yevhenii-nadtochii opened this issue Oct 5, 2023 · 0 comments
Open

Passing of a custom MetadataKey leads to an exception #70

yevhenii-nadtochii opened this issue Oct 5, 2023 · 0 comments
Labels
bug Something isn't working

Comments

@yevhenii-nadtochii
Copy link
Collaborator

There is a method io.spine.logging.ScopedLoggingContext.Builder.withMetadata(key: MetadataKey<T>, value: T) for attaching context metadata. It accepts a metadata key, which is an interface: interface MetadataKey<T: Any>. An attempt to create an object that implements this interface and pass it to the builder leads to an exception on JVM.

A failing code snippet:

import io.spine.logging.LoggingFactory
import io.spine.logging.MetadataKey
import io.spine.logging.WithLogging
import io.spine.logging.context.ScopedLoggingContext

typealias User = String

object UserKey : MetadataKey<User> {
    override val canRepeat: Boolean = false
    override val label: String = "user"
    override fun cast(value: Any): User =
        if (value is User) value else error("The passed `$value` can't be cast to `User`.")
}

object Example : WithLogging {
    fun doAct() {
        val user: User = "Bill"
        val logger = LoggingFactory.forEnclosingClass()
        ScopedLoggingContext.newContext()
            .withMetadata(UserKey, user)
            .execute {
                logger.atInfo().log { "..." }
            }
    }
}

fun main() = Example.doAct()

It fails with the following exception:

Exception in thread "main" java.lang.ClassCastException: class logging.test.UserKey cannot be cast to class io.spine.logging.JvmMetadataKey (logging.test.UserKey and io.spine.logging.JvmMetadataKey are in unnamed module of loader 'app')
        at io.spine.logging.context.DelegatingContextBuilder.withMetadata(LoggingContextFactory.kt:180)
        at logging.test.AppKt.main(App.kt:38)
        at logging.test.AppKt.main(App.kt)

However, it works fine if a key is created by LoggingFactory:

val userKey = LoggingFactory.singleMetadataKey("user", User::class)

We should either document somewhere that keys can be created only by the factory, or allow passing of custom ones.


Additionally, align naming of method arguments in overloads of singleMetadataKey(...) and repeatedMetadataKey(...). KClass for values is named different. We should go with valueClass name. It relates to LoggingFactory for JVM.

@yevhenii-nadtochii yevhenii-nadtochii added the bug Something isn't working label Oct 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant