最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

go - How to make Viper Unmarshal return an error if an env var is not set in Golang? - Stack Overflow

programmeradmin0浏览0评论

I'm using Viper in Golang to load configuration values from environment variables. However, I want viper.Unmarshal to return an error if a required environment variable is not set.

By default, if an environment variable is missing, viper.Unmarshal does not fail—it simply assigns the zero value to the struct field.

Here's my code:

package main

import (
    "fmt"
    "log"

    "github/spf13/viper"
)

type Config struct {
    DatabaseURL string `mapstructure:"DATABASE_URL"`
}

func main() {
    viper.AutomaticEnv()

    var config Config
    if err := viper.Unmarshal(&config); err != nil {
        log.Fatalf("Error unmarshaling config: %v", err)
    }

    fmt.Println("Config:", config)
}

If DATABASE_URL is not set, config.DatabaseURL is just an empty string instead of causing an error.

I tried using viper.BindEnv("DATABASE_URL"), but Unmarshal still does not fail when DATABASE_URL is missing.

In Viper, the Unmarshal function accepts hooks through DecoderConfigOption. Looking into viper, I found that the DecoderConfig struct has an ErrorUnset field:

// If ErrorUnset is true, then it is an error for there to exist  
// fields in the result that were not set in the decoding process  
// (extra fields). This only applies to decoding to a struct. This  
// will affect all nested structs as well.  
ErrorUnset bool 

However, I’m not sure how to pass this configuration properly as a hook in Unmarshal. If anyone knows how to enable ErrorUnset using DecoderConfigOption, thank you!

How can I make viper.Unmarshal DecodeHook return an error if a required environment variable is not set?

I'm using Viper in Golang to load configuration values from environment variables. However, I want viper.Unmarshal to return an error if a required environment variable is not set.

By default, if an environment variable is missing, viper.Unmarshal does not fail—it simply assigns the zero value to the struct field.

Here's my code:

package main

import (
    "fmt"
    "log"

    "github/spf13/viper"
)

type Config struct {
    DatabaseURL string `mapstructure:"DATABASE_URL"`
}

func main() {
    viper.AutomaticEnv()

    var config Config
    if err := viper.Unmarshal(&config); err != nil {
        log.Fatalf("Error unmarshaling config: %v", err)
    }

    fmt.Println("Config:", config)
}

If DATABASE_URL is not set, config.DatabaseURL is just an empty string instead of causing an error.

I tried using viper.BindEnv("DATABASE_URL"), but Unmarshal still does not fail when DATABASE_URL is missing.

In Viper, the Unmarshal function accepts hooks through DecoderConfigOption. Looking into viper, I found that the DecoderConfig struct has an ErrorUnset field:

// If ErrorUnset is true, then it is an error for there to exist  
// fields in the result that were not set in the decoding process  
// (extra fields). This only applies to decoding to a struct. This  
// will affect all nested structs as well.  
ErrorUnset bool 

However, I’m not sure how to pass this configuration properly as a hook in Unmarshal. If anyone knows how to enable ErrorUnset using DecoderConfigOption, thank you!

How can I make viper.Unmarshal DecodeHook return an error if a required environment variable is not set?

Share Improve this question edited Mar 30 at 11:55 Yossich asked Mar 30 at 9:35 YossichYossich 631 gold badge1 silver badge8 bronze badges 1
  • I don't use Viper but I suspect (!?) that you should validate the unmarshaled result. The Go Playground includes a go-playground/validator package that's powerful and may help. Here's a trivial example – DazWilkin Commented Mar 30 at 21:27
Add a comment  | 

1 Answer 1

Reset to default 1

I'm not sure if my answer is as described in your question, but you can refer to it.You can use the following code. I found that when we set ErrorUnset=true, we will check if we have set the required environment variables during unmarshal.

package main

import (
    "fmt"
    "log"

    "github/go-viper/mapstructure/v2"
    "github/spf13/viper"
)

type Config struct {
    DatabaseURL string `mapstructure:"DATABASE_URL"`
}

func main() {
    viper.AutomaticEnv()
    var config Config
    if err := viper.Unmarshal(&config, func(dc *mapstructure.DecoderConfig) {
        dc.ErrorUnset = true // Set ErrorUnset field to true here
    }); err != nil {
        log.Fatalf("Error unmarshaling config: %v", err)
    }
    fmt.Println("Config:", config)
}
// output 
2025/03/31 10:38:09 Error unmarshaling config: decoding failed due to the following error(s):

'' has unset fields: DATABASE_URL
exit status 1
发布评论

评论列表(0)

  1. 暂无评论