5 ms·
Yeah, I agree about wrapping. I actually usually try to avoid just doing return err, because you're losing some context that this code understands that the bel
by NateDad 12y ago
Yeah, I agree about wrapping. I actually usually try to avoid just doing return err, because you're losing some context that this code understands that the below code doesn't.... like if you return a FileNotFound error, the caller might not know why you were looking for that file, so you should wrap it and say fmt.Errorf("couldn't find config file: %s", err), that way if the user sees the error message, he'll see "couldn't find config file: open: file not found: foo.yml" instead of just "open: file not found: foo.yml".
- jerf 12y agoFlatting the error to a string isn't a good idea, unless you're sure you're dumping it straight out to the user (and by that I mean literal human, not merely "caller"). If you're returning it from a function, you need to wrap it, as in the Rust examples, so the caller can extract the original if they want to do something about it.
- mercurial 12y agoLike localizing it, for instance. Having a message is fine, having weakly-typed errors in production-quality code isn't.
- NateDad 12y agoWell, so there's two theories there... there's the theory you're saying, that the caller might want to know it's a filenotfound, and handle it programmatically... and there's the theory that the fact that you're doing file I/O is an implementation detail that callers shouldn't depend on, because it could change. What side of that argument you fall on depends a lot on the specifics of your code, and how much you want to sanitize your errors (and how likely you think callers will actually be able to do something programmatically about an error). I agree with both sides, and what I do in any particular situation depends a lot of on the details of what I'm doing.
- jerf 12y agoNo, this doesn't fit either case. If you are going to return the error details in a way the human user can read, then you really ought to just return them symbolically, because a programmer will start running regexes over your error codes to figure out what happened. If you're going to not show the underlying error, then either be willing to entirely hide it (sometimes appropriate, probably not for the usual IO case but there are internal errors for which a translation is appropriate) or wrap and pass up, but don't wrap and pass up as a string. That's the worst of all worlds.
- NateDad 12y agoI'm pretty much never going to feel bad about breaking someone's code that runs a regex over the error message I return. I can't stop people from writing bad code. Then again, I'm also careful to write my own code such that consumers of it always have a reasonable way to programmatically detect all the errors I know exist, and anything else is just "something really unexpected went wrong, here's a string to log if you want to". There's always going to be a category of errors that your code just doesn't understand. Giving the caller a string to log with some context is a lot better than returning just a generic error with no context. Returning the specific error is also possible, and sometimes that may be appropriate, but it can cause just as many problems as the other way... but at least the guy writing a regex should know better, and anyone who reads his code is going to notice it and tell him it's very likely to break. However, if someone type-checks the error you're returning, that looks like pretty valid code, so it's less likely to get red-flagged.... until you change your implementation, and that code now breaks. I really don't think we disagree terribly much on this btw. Like I said, it depends a lot on the situation. Defining policies for errors is hard. There's always tradeoffs, like anything else.