By day I work with a team in a language that sees errors ride on the exception handling system. Staying within the original example, I see code like this all the time (too often, even, but that's another topic for another day):
try {
file = getFile()
} catch(/* ... */) {
fileUnavailable()
}
Here, the assumption of getFile that the caller wanted an error was incorrect. A Result-using language would end up in a similar place.Idiomatic Go says leave it to the caller. Like above, when only wants to know if there is "file or no file" without concern for why there is no file, then:
file, _ := getFile() // The second return argument is an error.
if file == nil {
fileUnavailable()
}
I doubt either way makes much difference in this contrived example, but the difference shows up when it extends out into real code. There are plusses and minuses to each way of seeing the world. Tradeoffs, as always.