IO read/write functions are not limited to the net package. net.Conn supports a subset of these (interface types) and it is entirely idiomatic and possible for a net.Conn flavor to endup at some deep layer of your code in a function accepting generic io in args.
Functions taking non-net "in args" returning "error" can not be assumed to always return "net.Error". You will need to test the type (reflectively) and then safely cast.
To be clear, the two-valued cast I used in my example never panics. It returns (casted value, true) or (nil, false). No need to write any reflective functions.
As to your example of io.ReadFull: what about it? If it gets an EOF before filling the buffer you passed in, it'll return ErrUnexpectedEOF per the documentation. If it gets any other error, it'll return it instead. I haven't actually looked at the source in a while but that's how almost all of the byte stream functions work.