> Regarding an exception approach -- at a business level, the user cares that the log hasn't been written. Only one exception is needed to report that (so long as the exception includes the cause).

I thought I made it clear that example was intended to be more illustrative than literal, but obviously not. However there will clearly be occasions when exceptions are too blunt of a tool. Maybe think back to one of those occasions?

> The causative IO exception should indicate which operation failed (open or write), and -- for those with access to source -- should indicate the line number.

You're making a lot of assumptions there:

- that any imported libraries have well written error messages (sometimes they don't but they still the best at handling normal operation).

- that there is only one operation of a given type within a function (eg what if you're writing to two different logs? It would certainly help to wrap that error with which log you're writing a generic error for the whole function)

- that the person debugging the executable has access to the source code -- or even understands the language enough for the source to be of use. The target audience might not even be technical so having useful error messages that they can report back to support helps reduce the cost on your support team

> Encapsulation principles suggest that both the user & calling code should care only that the log was written successfully (or not), but not how or why it succeeded or failed.

Not entirely true. Code shouldn't care but humans who would need to rectify the fault definitely DO care. eg how often do people on HN comment about the usefulness of Rust's compiler messages? It's exactly the same principle you're now arguing against.

Also the log example is illustrative.

> Any recovery in code (if possible, usually it's not) should be encapsulated within the method.

The example I'd written does exactly that. So we're all good then ;)

> In most error cases there is no realistic or sound recovery (occasionally a generic retry might be valid). The main purpose of error handling is to stop successfully and report the problem in a diagnosable manner.

That's a rather large generalisation and often isn't true eg

- Some frameworks return EOF as an error state when reading past the end of a file (eg from pipes).

- If you're running a web service and someone's connection terminates while you're still writing to it, that would produce an error but you'd obviously need to recover otherwise your whole web service crashes.

Errors and exceptions are a pretty normal way of breaking control flow and aren't just used in edge cases where the application should be terminated in a controlled manor.

> Some context on the purpose of error handling/exceptions in this article: http://literatejava.com/exceptions/checked-exceptions-javas-.... .

I've been writing Java since v1 days. In fact I have 30 years of development experience in dozens of languages. Java does a lot of things better than Go but frankly I'd take Go's error system over Java's.

I think the biggest drawback of Go's error system is it's manual and verbose. Ironically that's also it's strength, as in that's why it works (as I described in my previous post). However from the perspective of developers looking from the outside in, err blocks just luck ugly. Which I also get. Sometimes it is a chore writing err blocks but they are also immensely useful in practice (and when isn't it tedious capturing errors?)