go中将错误分组的最佳方法是什么?

时间:2013-07-11 14:02:49

标签: go

我在看net / http和crypto / x509

我想知道哪种方法更好,为什么。

net / http / http.go使用字符串:

// HTTP request parsing errors.
type ProtocolError struct {
  ErrorString string
}

func (err *ProtocolError) Error() string { return err.ErrorString }

var (
  ErrHeaderTooLong        = &ProtocolError{"header too long"}
  ErrShortBody            = &ProtocolError{"entity body too short"}
  ErrNotSupported         = &ProtocolError{"feature not supported"}
  ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
  ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
  ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
  ErrMissingBoundary      = &ProtocolError{"no multipart boundary param in Content-Type"}
)

crypto / x509 / verify.go使用ints:

type InvalidReason int

const (
  TooManyIntermediates
  IncompatibleUsage
)

type CertificateInvalidError struct {
  Cert   *Certificate
  Reason InvalidReason
}

func (e CertificateInvalidError) Error() string {
  switch e.Reason {
  case TooManyIntermediates:
    return "x509: too many intermediates for path length constraint"
  case IncompatibleUsage:
    return "x509: certificate specifies an incompatible key usage"
  }
  return "x509: unknown error"
}

1 个答案:

答案 0 :(得分:1)

这两种用法都很好,但这取决于您的需求。

如果您发现将其他数据附加到错误消息中未显示的错误很有用,那么crypto/x509中的方法更可取。

但我认为在大多数情况下,errors包中的简单错误字符串就足够了。

修改

错误可以有不同的“属性”:

<强>描述
Error()方法应该返回一个简短描述错误消息

<强>身份
通过让包导出它可能返回的不同错误,您可以识别它们。这可以通过导出相同类型的初始化错误变量在io包中完成:

if err == io.EOF { ... } // That's easy

或者像导出不同错误类型的encoding/json包一样:

if mErr, ok := err.(*json.MarshalerError); ok { ... } // That's fairly easy

或者通过在crypto/x509包中执行操作,导出不同的原因(错误代码):

if e, ok := err.(x509.CertificateInvalidError); ok && e.Reason == x509.Expired  { ... } // Well, it works

唯一错误代码
如果由于协议规范而导致错误具有特定代码,则这些代码可以嵌入到错误变量中。可能会使用crypto/x509包,即使情况可能并非如此。

但是当涉及到如何解决它时,我认为没有最佳方法,也没有任何明确的惯用方法。上面的示例显示了执行此操作的方法以及在标准库中完成的方法。随便挑选。

..但可能没有使用switch语句。