On Sun, Jan 12, 2020 at 4:39 PM <pboampo...@gmail.com> wrote:
>
> Up until now I've been in the habit of checking Close errors on files written 
> to, but I never closed os.Stdout after use (for the purpose of error 
> reporting), and now I'm thinking that's inconsistent.
>
> In this commit message [1], Ian Lance Taylor wrote: "Programs should always 
> check the error return of Close for a file opened for writing."
>
> Does this imply that if I use os.Stdout I need to Close it and check the 
> error? If no, why is that different?
> I see no reason to expect weaker error reporting for stdout than any other 
> file opened by the program itself.
>
> For example gofmt doesn't close stdout, therefore this command could silently 
> produce an incomplete output on a close-only error:
> $ gofmt foo.go >bar.go
>
> On the contrary, the Gnu coreutils for example, always close stdout and check 
> the error, therefore this cat would report it and exit non-zero:
> $ gofmt foo.go | cat >bar.go
>
> It seems inconvenient to always Close and check os.Stdout after use: I would 
> have to arrange for it in the majority of my programs, even the most simple.
> But if I don't do that, why should I bother to check any os.File.Close error 
> at all? In a class of equally important errors, if I'm ignoring some of them 
> for no particular reason, I might as well ignore all of them.
> What's your opinion?
>
> In this old thread [2], Rob Pike wrote: "If the situation requires you to 
> handle errors on close, handle them. If it does not, you can defer the close. 
> That's all there is to it."
>
> Specific situations may call for specific error handling, but unfortunately 
> in the vast majority of cases there is little assumptions I can make. If the 
> data is not on its way to the disc I want to tell the user, but not at the 
> cost of much boilerplate if the condition is rare enough. I want to meet 
> general expectations and be consistent.
> (Telling the user usually means to print a message and/or make sure the exit 
> status is non-zero.)
>
> "defer f.Close()" is common in the wild, even for files written to. Many new 
> users learn it as a general pattern because the read-only "requirement" is 
> rarely discussed (for example Effective Go doesn't mention it in its "defer 
> f.Close()" example).
>
> It seems that, with most filesystem drivers, an EIO error that is not 
> reported by Write has a high chance to be missed by Close too (unless you 
> also call Sync), because a Close doesn't necessarily initiate any writeback 
> from the kernel.
> So I wouldn't worry about EIO from Close (unless I also use Sync) because I 
> already accepted the compromise, therefore I'm left with ENOSPC or EDQUOT 
> (i.e. "no space left" errors).
> Is it possible that Write doesn't report ENOSPC or EDQUOT but Close does? 
> According to the Linux close(2) man page, yes, on NFS; what about anything 
> else?
>
> The same man page was changed from: "Not checking the return value of close() 
> is a common but nevertheless serious programming error"
> to: "A careful programmer will check the return value of close()".
> Now, that is helpful! :D
>
> In summary I'm looking for a rule of thumb: should I check the Close error 
> for files written to? Should I Close and check os.Stdout after use (for the 
> purpose of error reporting)? For consistency I would expect either yes to 
> both questions or no to both questions.
> Thanks to anyone who read this far.

The difference between os.Stdout and other files is: if writing to
os.Stdout fails, where are you going to report the error?  You could
report it to os.Stderr, of course, but if os.Stdout doesn't work then
it is very likely that os.Stderr also doesn't work.  There is no point
to checking for an error that you have no way to report.

So my personal general guideline is: always check for, and report,
errors on files opened for writing, but don't worry about os.Stdout.

Of course it may be appropriate to make an exception in certain
circumstances.  That is just a general guideline.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVUMAmctEKr3JC_6JqjBcOzMbJyeZUXv%3DWYU9jeQS_vEQ%40mail.gmail.com.

Reply via email to