Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: document that OpError.Err field must be non-nil #33007

Open
dunjut opened this issue Jul 9, 2019 · 3 comments

Comments

Projects
None yet
3 participants
@dunjut
Copy link

commented Jul 9, 2019

In one of my unit tests, I passed new(net.OpError) to the tested function and that function logs the error and does some recovery logic (like re-connect).

Logging such err calls *OpError's Error() method, which panics because we didn't check the Err field.

Though in most cases we won't get an OpError like this in real scenarios, I suggest maybe checking on Err field still gives better preciseness?

@dmitshur

This comment has been minimized.

Copy link
Member

commented Jul 15, 2019

Thanks for the report.

I see that the case of *net.OpError being nil is currently supported:

func (e *OpError) Error() string {
	if e == nil {
		return "<nil>"
	}
	[...]
}

But *net.OpError being non-nil with a nil Err field is not (since it panics).

I'm going to move this issue to the needs decision state.

The decision is whether *net.OpError should support users creating it with the Err field set to nil, or if such use is considered invalid and should not be supported. (As far as I can tell, this can only happen if users create *net.OpError themselves, and none of the functions in net package actually return a *net.OpError with nil Err field.)

If it should be supported, then it should check if Err is non-nil before calling Err.Error() (to avoid the panic).

If it shouldn't be supported, perhaps we can make the documentation a little more explicit about that:

 // OpError is the error type usually returned by functions in the net
 // package. It describes the operation, network type, and address of
 // an error.
 type OpError struct {
 	[...]

 	// Err is the error that occurred during the operation.
+	// It must be non-nil.
 	Err error
 }

I would argue that it shouldn't be supported, because supporting non-nil *net.OpError with a nil Err field does not make sense and it's not clear what it would represent. If there was network error, then OpError.Err should be non-nil. If there wasn't an error, there shouldn't be a *net.OpError type wrapping it.

/cc @mikioh @ianlancetaylor per owners.

@dmitshur dmitshur added this to the Go1.14 milestone Jul 15, 2019

@dmitshur

This comment has been minimized.

Copy link
Member

commented Jul 15, 2019

The if e == nil { check was added by @adg in CL 1848049, so I'll /cc him in case he has opinions on this issue.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jul 15, 2019

The whole point of OpError is add details to a lower-level error. It is meaningless to have a net.OpError with an Err field that is nil. Let's just document that fact and move on.

@dmitshur dmitshur changed the title net: *OpError.Error() should check its Err field net: document that OpError.Err field must be non-nil Jul 15, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.