Golang中这些错误是否常见?如何解决?

Golang中这些错误是否常见?如何解决? 在从yaml读取配置时,我注意到如果文件不存在,以下示例中不会出现任何错误。

	viper.SetConfigType("yaml")

	file, _ := os.Open("example.yaml") //此文件不存在
	defer file.Close()

	err := viper.ReadConfig(file)
	if err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			log.Fatal("configuration file not found")
		} else {
			log.Fatal(err)
		}
	}

以上错误都没有发生。如果文件不存在,这难道不是ConfigFileNotFoundError吗?


更多关于Golang中这些错误是否常见?如何解决?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

Os.Open 返回一个布尔值指示文件是否存在,但你在调用中忽略了这一点。

你可以将调用改为:

file,err := os.Open("example.yaml") //此文件不存在
  if err != nil {
    log.Fatal(err)
  }
  defer file.Close()

更多关于Golang中这些错误是否常见?如何解决?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在您的代码示例中,当文件不存在时确实不会触发 ConfigFileNotFoundError,这是因为错误处理逻辑存在根本问题。

问题分析:

  1. os.Open("example.yaml") 在文件不存在时会返回错误,但您使用了空白标识符 _ 忽略了该错误
  2. 当文件不存在时,file 变量为 nil,后续对 nil 文件执行操作才是真正的错误来源
  3. viper.ReadConfig 接收的是已打开的文件句柄,它不负责检查文件是否存在

正确解决方案:

viper.SetConfigType("yaml")

file, err := os.Open("example.yaml")
if err != nil {
    if os.IsNotExist(err) {
        log.Fatal("configuration file not found")
    } else {
        log.Fatal("error opening config file:", err)
    }
}
defer file.Close()

err = viper.ReadConfig(file)
if err != nil {
    log.Fatal("error reading config:", err)
}

更简洁的替代方案(使用Viper内置方法):

viper.SetConfigFile("example.yaml")
viper.SetConfigType("yaml")

err := viper.ReadInConfig()
if err != nil {
    if _, ok := err.(viper.ConfigFileNotFoundError); ok {
        log.Fatal("configuration file not found")
    } else {
        log.Fatal("error reading config:", err)
    }
}

关键点:

  • ConfigFileNotFoundError 只在调用 viper.ReadInConfig() 时才会被触发
  • 直接使用 os.Open 时需要自行处理文件不存在的错误
  • 始终检查 os.Open 返回的错误,不要使用空白标识符忽略
回到顶部