spf13 / viper

Go configuration with fangs
MIT License
26.93k stars 2.02k forks source link

UnmarshalExact() returns misleading error message #1724

Open ardrabczyk opened 9 months ago

ardrabczyk commented 9 months ago

Preflight Checklist

Problem Description

Example:

package main

import (
        "bytes"
        "log"

        "github.com/spf13/viper"
)

type settings struct {
        URL      string
        Username string
        Password string
}

func main() {
        viper.SetConfigType("toml")

        confContents := []byte(`
url = 'http://localhost'
username = 'my-user'
password = 'my-password'
extra = 'fake'
`)

        _ = viper.ReadConfig(bytes.NewBuffer(confContents))
        settings := settings{}
        err := viper.UnmarshalExact(&settings)
        if err != nil {
                log.Fatal(err)
        }
}

Output:

$ go run .
2023/12/20 10:52:40 1 error(s) decoding:

* '' has invalid keys: extra
exit status 1

Can this * '' has invalid keys: extra error get more readable? I especially don't like '' part, it's very misleading for users and isn't helpful for them.

I know it comes straight from https://github.com/mitchellh/mapstructure/blob/main/mapstructure.go#L417 but can it maybe be made more readable here?

Proposed Solution

I would like the error message to be more readable and do not mention a suspicious '' part.

Alternatives Considered

No response

Additional Information

No response

github-actions[bot] commented 9 months ago

👋 Thanks for reporting!

A maintainer will take a look at your issue shortly. 👀

In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.

⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9

📣 If you've already given us your feedback, you can still help by spreading the news, either by sharing the above link or telling people about this on Twitter:

https://twitter.com/sagikazarmark/status/1306904078967074816

Thank you! ❤️

ardrabczyk commented 9 months ago

I found I can always do

var md mapstructure.Metadata
err = viper.Unmarshal(&settings, func(config *mapstructure.DecoderConfig) {
                config.Metadata = &md
        })

and then loop through md.Unused but UnmarshalExact() doesn't set it, I don't yet know why.

EDIT:

decodeStructFromMap() returns early when ErrorUnused is set https://github.com/mitchellh/mapstructure/blob/main/mapstructure.go#L1459