管理golang中的错误

时间:2015-06-19 04:44:03

标签: go

我来自Ruby,目前正在看Go。我开始编写一些代码来检查给定主机的TLS支持。

var tls_versions = map[uint16]string{
  tls.VersionSSL30:  "SSLv3",
  tls.VersionTLS10:  "TLSv1.0",
  tls.VersionTLS11:  "TLSv1.1",
  tls.VersionTLS12:  "TLSv1.2",
}

var refused_re = regexp.MustCompile(": connection refused")
var nodns_re = regexp.MustCompile(": no such host")
var versionnotsupported_re = regexp.MustCompile(": protocol version not supported")

func checkversion(host string) (map[string]bool, error) { // {{
  ret := map[string]bool{}

  for version := tls.VersionSSL30; version <= tls.VersionTLS12; version++ {
    conn, err := tls.Dial("tcp", host+":443", &tls.Config{
       MinVersion: uint16(version),
    })

    if err != nil && 
        (refused_re.MatchString(err.Error()) == true || nodns_re.MatchString(err.Error()) == true) { 
      log.Println(err)
      return ret, err
    }

    if err != nil && versionnotsupported_re.MatchString(err.Error()) == true  {
      ret[tls_versions[uint16(version)]] = false
      log.Println("Not supported: "+host+"  "+tls_versions[uint16(version)])
    }
    ret[tls_versions[uint16(version)]] = true

    if conn != nil {
      conn.Close()
    }
  }
  return ret, nil
} 

来自Ruby我发现这个代码中的错误管理非常难看,因为我是一个错误/改变远没有得到正确的错误原因。我试着玩反射,但无法让它做我想要的。我想知道我是否遗漏了一些显而易见的东西,或者它是不是这样?或者它是否特定于crypto / tls库以避免从任何问题中恢复?

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

Go中有可能进行良好的错误管理。

请参阅Dave C的this answer以获得一个很好的总结和很好的例子。

不幸的是,在tls套餐的情况下,您运气不好。您尝试检测的错误是由fmt.Errorf()次调用(委托给errors.New())生成的,因此它们在任何情况下都不是特殊的,并且它们没有预先声明,因此您无法做得更好比你目前的解决方案来区分它们。可能开发人员懒得提供更复杂或更容易追溯的错误,或者只是他们认为它不重要而且为了简单而被遗漏;所以他们目前更像是开发人员的信息。

进一步阅读(引自Dave C&#39的回答):