6 ms·
How does Go completely ignore run-time errors? For all I know it forces you to deal with them by treating them as values instead of exceptions.
by thwd 10y ago
How does Go completely ignore run-time errors? For all I know it forces you to deal with them by treating them as values instead of exceptions.
- aninhumer 10y agoHowever it treats them as product values (tuples) instead of sum values (Either), so it's perfectly possible to ignore the error and take the result anyway.
- junke 10y agoIgnoring on purpose is fine. The problem is when the only return value is an error which can be ignored simply by not assigning the result to a variable. Forcing the user to do: _ = f.Close() ... in order to explicitly ignore the error would be nicer, but then, there are many functions which are known to never be checked for their errors, like fmt.Println. That's why the typical advice is to use errcheck, which has filters to avoid "false"-positives (I am not convinced that some function never should be checked for errors).
- bsdetector 10y ago> functions which are known to never be checked for their errors, like fmt.Println In Java println is checked for errors, as it should be. Every Java program that does println either aborts or deals with the error in some way. It matters. Take any program that writes to stdout and run it with ">&-" to close stdout. Because of unix, the next file it opens will be file descriptor 1 and the program will start writing the console output to the file. You want the program to abort instead of trashing a file, and especially not to trash /etc/passwd. That's why you don't want to ignore errors, because any time you do there can be unintended and hard to imagine consequences -- even something as simple as writing to the console. Simply put, Go encourages buggy programs with poor error handling.
- AnimalMuppet 10y agoAnd the cynic in me says that, if you do that with a program that handles the password file, you almost deserve what you're going to get...
- echlebek 10y agoI tried your example, and observed an error: write /dev/stdout: bad file descriptor What "next file it opens" are you talking about exactly? How does what you're describing work?
- bsdetector 10y agoIn unix when you open a file it gets the lowest available file descriptor number. So if you run a program with no stdout (file descriptor 1) then it gets a "bad file descriptor" error anytime it prints something until a file is opened, gets file descriptor 1, then it starts writing to the file. Example: #include <stdio.h> int main(int argc, char **argv) { printf("first message\n"); fflush(stdout); fopen("output", "w"); printf("second message\n"); fflush(stdout); } Output: # ./a.out first message second message # ./a.out 1>&- # cat output second message By ignoring the error, the program continued on and then wrote console output messages to the file after it was opened. There have been exploits due to this bug, but the real point is that you could never predict this failure without good knowledge of unix and careful consideration. This is why error codes should not be cavalierly ignored, because it's really hard to know what might happen if you do. Last I checked, Go operates the same way as this C example. Java fails on the "first message" if stdout is closed so it doesn't trash the file, not because they even specifically thought of this scenario but just because errors are not ignored by default and are not easy to ignore.
- pmarreck 10y agoHow does treating them as values force you to deal with them (except on principle)? Does the language force you to check the return value of every line of code? And the checking would only encompass expected errors, not unexpected ones, no? The unexpected ones (read: bugs) would simply be swallowed up and the actual problem would finally turn up far away in some other stack scope, no?
- thwd 10y agoTrue, you can discard errors on purpose by assigning them to "_", which is an explicit way of saying "I do not care about this error happening". If you do that and get a panic down the line, you already know where to start debugging. That's much better than having an exception bubble up from deeeeep inside your code with some context-less cryptic message or number, isn't it?
- junke 10y ago> If you do that and get a panic down the line... No, you don't panic, you are most likely to corrupt your data and maybe continue working as if everything was fine. If you are lucky, your code panics. > ... you already know where to start debugging. Grep all occurrences of "_"? > That's much better than having an exception bubble up from deeeeep inside your code with some context-less cryptic message or number, isn't it? No, the exception carries all the context you need. If you ignored a previous exception, the next one won't be as useful as it could, but at least your code breaks loudly.
- bsdetector 10y agoAlso "_" means the programmer chose to ignore the errors that he knew about at the time. There's no way to know whether the programmer actually considered all the error cases (they are generally very poorly documented in Go code), and there's no way to know if the called function added errors at some later date. If it's though an interface, there's no way to know that all implementations have the same errors. It's really an 80s-era approach to error handling, and that's bad.
- 10y ago
- junke 10y agoGo forces you to use errcheck.