3 ms·
Serious question: why is the error return from Println not handled?
by millstone 8y ago
Serious question: why is the error return from Println not handled?
- reificator 8y agoThere are two main reasons: 1. Many developers learn the print funcs before they really start paying attention to errors as return values, and so never think to check what it returns. 2. If println is failing, things are going very wrong. It would probably be more ergonomic to just have it panic in most cases, because if it errors out then what are you honestly going to do to recover gracefully? Just let your surrounding infrastructure handle it, whether that's restarting the process, starting a new container somewhere else on the cluster, or whatever.
- skybrian 8y agoIf stdout is unavailable, should that really be fatal? Perhaps it should be considered an unusual equivalent to piping to /dev/null.
- reificator 8y agoWhich is the current practice of ignoring errors from `fmt.Println()`.
- deleted 8y ago[deleted]
- jerf 8y agoIn general, catching errors when there is simply nothing useful to do with them isn't that useful. If the world is so broken that printing isn't working, it probably isn't the print failing that you care about. Even the errcheck linter, which I use in all my serious code, doesn't make you check the error from basic print statements like that. (Fprint it makes you check. But not just Print.)
- mike_hearn 8y agoThen why does Print return an error code at all?
- axaxs 8y agoSo if the printing doesn't work, you can see what's going on?
- mike_hearn 8y agoBut all the comments in response to the question are saying there's no point in checking the return code of print, because if it's broken, you can't print the error code you got anyway (or it's never broken in practice). I think there's a deeper point the question asker was making here - it's easy to say "everyone should just check error codes" but in practice it never works out that way. People always ignore/swallow some of them, or propagate them in such a way that they lose detail e.g. a detailed error code from a subsystem is mapped to a generic error code higher up the abstraction stack. Print failing is a classic example of something most wouldn't care to check, but perhaps there's a good reason for it. With exceptions in the common case, where nobody checked, an exception would propagate up the stack until it was either caught and handled in a generic way ("subsystem X failed") or simply caught by the runtime.
- nomel 8y agoThere's no reason to care about print being broken, unless there's a reason to care about print being broken. Both cases need to be supported. The developer ignoring the error value if they don't care is perfectly rational.
- jerf 8y ago"But all the comments in response to the question are saying there's no point in checking the return code of print" That's not quite what I said, and the difference is important. I said there's no point catching an error when you have nothing useful to do with it. It so happens that the basic "print to standard out" is the extreme outlier of a function where you have nothing very useful to do with it in the general case. What are you going to do, print an error? Are you going to log it? Probably not, because if you have a log in the first place you probably aren't seriously using printing. There are exceptions where you might care, such as a command-line program where printing is the major case you care about, but it so happens that the printing functions often have nothing useful to do with errors. It is not the only case. I often don't log things terribly strongly during the time a socket is being shut down at some point in a protocol where both sides have agreed to shut the connection down, for instance. Or if I have a socket connection and the underlying connection fails, I don't need an individual log message for every concrete manifestation of that fact necessarily. If logging fails... uhh... what exactly is one supposed to do with that information in the general case? So even though I use errcheck like I said on all my code, there are places where I throw the error away on purpose. It's clearly indicated in the code, though, rather than being implicit, since errcheck requires a "_ = erroringThing()" line of code. Except for printing to stdout, because as a special case, that's just too common a case to worry about, even when one is careful enough to use a linter for everything else.
- jagger27 8y agoI'm having a hard time making it fail. Even with Printf, in the output it tells you what you did wrong instead of returning an error. In fact, the only _print function I could get to fail was Fprintf by sending an already closed file. I suppose if it was somehow not allowed to write to stdout the other functions might fail. But I'm not sure. _, err := fmt.Printf("Hello %d", "world") fmt.Println(err) >> Hello %!d(string=world) >> <nil>
- ianlancetaylor 8y agoYes, the various fmt.Print functions only return an error if Write on the underlying Writer returns an error.
- TheDong 8y agoHere you go: https://play.golang.org/p/0vGdejrjm5H https://play.golang.org/p/0vGdejrjm5H To reproduce the key lines here: os.Stdout.Close() _, err := fmt.Println("foo") You can also close stdout from outside the program, use ptrace to cause the write call to fail, or a number of other things.
- grey-area 8y agoIn this particular example there is no good reason, it’d be better to end with: return fmt.Println()