I’m writing a lib to interact with a web service for a lesser known cloud storage service. One of the functions in this lib is NewUserClient which (as you may expect) creates a new Client object that’s used to interact with this web service. This call needs to do some back and forth with the API to convert a username and password to an API token that can be included in a header to authorize subsequent requests. Because of this back and forth with an http.Client, an error can be returned. I’m not a very experienced Go programmer but based on my limited exposure to a handful of Go packages, it does not seem common to create a NewX function return (X, error). This leads me to wonder if I should either:
Avoid multiple return values from a NewX function; either:
Defer any errors until the first function that has an error in its return values
Panic (I don’t think this is the right way to do this, but it’s very Pythonic/C#-ic/Java-ic (note also that I know Go is not Python/C#/Java )).
put an Err() function or something similar on the returned object that can get whatever the last error was.
Use a different naming convention (e.g. CreateX).
I don’t know which if any of these options is the right fit. Are there others I haven’t considered? Are any a good default / de-facto standard that I should prefer unless I have a reason not to?
It may make more sense to make this something like Authenticate(username, pw string) (*Clent, error) because then it becomes clear that you need to authenticate the data before returning a client.
Another option is to have NewClient return a client with a method like Authenticate and have that return an error if it is invalid.
Thanks for your reply, Jon, I like the idea of having a function with a name other than NewX that makes it clear that this doesn’t just return an X but at the same time I don’t think it’s obvious that a name like Authenticate will give me a new Client without me having to check my own documentation in the future (assuming I don’t end up using this package very frequently). I like the idea of stumbling into the “pit of success” if at all possible!
For the same reason, I don’t really like the idea of using a separate Authenticate method to authenticate the Client because it’s possible that a user of the API will forget to use this function after they construct the Client. I’d like the construction/initialization of the client to be a single function call (from the public API) to eliminate the possibility of using the Client incorrectly.