Skip to content

errors: ErrUnsupported should document expected side effects #63942

Description

@dsnet

I'm struggling to figure out how to correctly use errors.ErrUnsupported.

In the proposal, @rsc gave this example:

func (w) WriteString(s string) (int, error) {
    if u, ok := w.u.(io.StringWriter); ok {
        return u.WriteString(s)
    }
    return 0, ErrTBD
}

where ErrTBD is presumably what became ErrUnsupported.

Let's say hypothetically, we wanted to make io.WriteString make use of errors.ErrUnsupported, what would that look like?

func WriteString(w Writer, s string) (n int, err error) {
	if sw, ok := w.(StringWriter); ok {
		switch n, err := sw.WriteString(s); {
		case err == nil:
			return n, nil
		case !errors.Is(err, errors.ErrUnsupported)):
			return n, err
		}
		// otherwise err is errors.ErrUnsupported, fallback on other logic
	}
	return w.Write([]byte(s))
}

However, the only way this is possibly correct is if returning errors.ErrUnsupported also indicates that the operation had no side-effects and could thus be retried in an alternative way. As of right now, there is no such documented guarantee.

If we do document that errors.ErrUnsupported is side-effect free, then it also means that this is error prune (pun intended) where returning the error up the call stack increases the probability that there are indeed side-effects from other operations.

\cc @ianlancetaylor @bcmills

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions