var errors stdlib

134 views
Skip to first unread message

Sebastian Bogan

unread,
May 10, 2024, 12:03:46 PM5/10/24
to golang-nuts
Hello Everyone,

I was wondering, what was / is the reason for exposing errors as public vars - rather than constants? Doesn't that impose some risk?

For example:

  fs.ErrNotExist = errors.New("foo")
  _, err = os.ReadFile("./invalid")
  if !errors.Is(err, fs.ErrNotExist) {
    fmt.Println("is NOT fs.ErrNotExist")
  }

Would something like the following work (and be less risky)?:

  type ConstError string
  func (e ConstError) Error() string {
    return string(e)
  }
  const ErrNotExist = ConstError("file does not exist")

Thanks
Seb

Dan Kortschak

unread,
May 10, 2024, 3:52:25 PM5/10/24
to golan...@googlegroups.com
Interface values cannot be consts per the spec. But to address the
concern, if some malicious or misguided package in your imports
reassigns a value to an exported error var, the example you show would
still work since the value is still common to all users of the var. If
the check were against the string returned by the Error method there
would be a problem, but that is advised against already. It could
potentially be a source of race conditions if the import made the
change after init and the read were happening in goroutine.

There are issues in the tracker that discuss const values,
https://go.dev/issue/6386 is probably a good place to start.

Brian Candler

unread,
May 10, 2024, 5:26:36 PM5/10/24
to golang-nuts
On Friday 10 May 2024 at 17:03:46 UTC+1 Sebastian Bogan wrote:
Would something like the following work (and be less risky)?:

  type ConstError string
  func (e ConstError) Error() string {
    return string(e)
  }
  const ErrNotExist = ConstError("file does not exist")

If you compare an error value against this constant, and the error value has the correct type, then you're actually doing a character-by-character comparison of the string text, not unique object identity.

 
Reply all
Reply to author
Forward
0 new messages