> On Feb 3, 2025, at 6:01 AM, Byungjun You <schiz...@gmail.com> wrote: > In Java, checked exceptions allow developers to define in advance which > exceptions a function can throw. However, it seems that Go does not have such > a feature. Would it be considered a best practice in Go to document the > possible errors that an API function can return? Additionally, what are some > best practices that API providers can follow to help API users handle errors > effectively? > In Go, errors are values[1] meaning most in the Go community frown on try-catch style exception handling as in Java.
Each function in Go which can generate an error will typically return that error as an additional value; e.g.: func (d Data) getValue() (value any, err error) { if d.value == nil { return nil, errors.New("value as not been set") } if reflect.ValueOf(d.value).IsZero() { return nil, errors.New("value is empty") } return value,err } Then getValue() would be called like this: value, err := data.getValue() See https://go.dev/play/p/PciRk_t_UaV <https://go.dev/play/p/PciRk_t_UaV> for full working example. In some cases — though not as many as I would like — Go developers often create sentinel values that might look like this: var ( ErrValueNotSet = errors.New("value as not been set") ErrValueIsEmpty = errors.New("value is empty") ) Then callers can check them using errors.Is() like so: if errors.Is(err, ErrValueNotSet) {...} if errors.Is(err, ErrValueIsEmpty) {...} See https://go.dev/play/p/pamY1pcAoVP <https://go.dev/play/p/pamY1pcAoVP> for a full working example. A common sentinel error value from the Go std lib is io.EOF[2] However, AFAIK, there is no way programmatically to determine which errors a Go function might return at this time. It would be nice if there were some built-in mechanism for doing that using the reflect package, but I would not expect that to be added as I cannot imagine how it could be implemented without slowing down compilation. Unfortunately. As for best practices, IMO that would be to define sentinel error variables instead of errors created inline with errors.New() or fmt.Errorf() for all errors that your function may return, and then use errors.Join() to join with any errors returned by a function your function called before returning to the caller. Then document your sentinel error variables and commit to not renaming or removing them in future versions of your API. Does that answer your question? -Mike [1] https://go.dev/blog/errors-are-values <https://go.dev/blog/errors-are-values> [2] https://github.com/golang/go/blob/beea7c1ba6a93c2a2991e79936ac4050bae851c4/src/io/io.go#L44 <https://github.com/golang/go/blob/beea7c1ba6a93c2a2991e79936ac4050bae851c4/src/io/io.go#L44> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/94A57D56-A71C-48A1-B279-D638E178FD6B%40newclarity.net.