> On Feb 3, 2025, at 6:01 AM, Byungjun You <[email protected]> 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 [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/golang-nuts/94A57D56-A71C-48A1-B279-D638E178FD6B%40newclarity.net.