News for hackers. Stuff that matters.
Re:Why Go's Error Handling Is Awesome by twic on Tuesday July 07, 2020 @09:12AM (#23758830)
IMNERHO, the one significant misstep in checked exception based error handling is that languages don't (AFAIK!) require call sites to be marked. If a function is marked as throwing an exception, and it's called from another function marked as throwing the same exception, that's enough. There's no indication to the reader that an exception can be thrown at a particular point, much less the the author was aware of the fact that it can!

Go's if (err != nil) { return err; } and Rust's ? both do that.

You could imagine a variant of Java where you had to write this:

  Byte readOptionalByte(InputStream in) throws IOException {
    int flag = try(in.read());
    if (flag == 0) return null;
    else return (byte) try(in.read());
  }
Which might be better.

Unchecked exception based error handling, of course, is irretrievably broken.

Re:Why Go's Error Handling Is Awesome by mabbo on Tuesday July 07, 2020 @09:35AM (#23759077)
> Unchecked exception based error handling, of course, is irretrievably broken.

The mental model I have with Java unchecked exceptions it that all methods, by default, have "throws UncheckedException" at the end of it. And since the calling line of code is also a method, it doesn't need to explicitly handle it.

What would be nice is a means to mark a method as "Cannot throw exceptions of any kind", removing the unspoken "throws UncheckedException" from the signature and forcing that method to internally handle all unchecked exceptions- enforced by the compiler.

Perhaps with the coming pattern matching to Java, we'll be able to resolve this with Return value wrapping types that are One-Of (return value type, Exception type 1, Exception type 2, etc...). Then you could call the method, and pattern match the result by type.

Re:Why Go's Error Handling Is Awesome by Someone on Tuesday July 07, 2020 @09:30AM (#23759010)
Swift essentially does that, but uses a try keyword, not something that looks like a function. See https://docs.swift.org/swift-book/LanguageGuide/ErrorHandlin....
Re:Why Go's Error Handling Is Awesome by 95th on Tuesday July 07, 2020 @09:19AM (#23758901)
Well, in Java's defense, at least you don't forget to check the error like you could in Go.
Re:Why Go's Error Handling Is Awesome by cy_hauser on Tuesday July 07, 2020 @10:00AM (#23759345)
While I'm no great fan of Go's error handling, I've not found this to be an issue. The compiler yells at you if you forget. You'd have to explicitly ignore the error by underscoring it to "forget" it.
Re:Why Go's Error Handling Is Awesome by apta on Tuesday July 07, 2020 @06:13PM (#23764737)
No it doesn't:

    err := foo()
    if err != nil {...}
    err = bar() // accidentally ignored
    err = baz()
    if err != nil {...}
Re:Why Go's Error Handling Is Awesome by eeereerews on Tuesday July 07, 2020 @09:18AM (#23758897)
How do you propose handling an OOB index in an array?
Re:Why Go's Error Handling Is Awesome by twic on Tuesday July 07, 2020 @09:33AM (#23759041)
I follow Joe Duffy in recognising that we should make a distinction between "errors" and "bugs" [0]. IOException is an error; out of bounds access, division by zero, assertion failures, and things like ClassCastException and NullPointerException in Java, are bugs.

For errors, you should do error handling, which means you want the compiler to make sure you don't miss them.

For bugs, you want to let the program bomb out, either aborting entirely or stopping at some high-level boundary from which it's possible to sanely continue. In Java, unchecked exceptions are a mostly adequate mechanism for that. Rust's catch_unwind is better, because it makes stronger guarantees [1]. Erlang's approach of terminating the thread and throwing away its heap is also very good, if you can apply that.

[0] http://joeduffyblog.com/2016/02/07/the-error-model/#bugs-are...

[1] https://doc.rust-lang.org/std/panic/fn.catch_unwind.html

Re:Why Go's Error Handling Is Awesome by eeereerews on Tuesday July 07, 2020 @10:20AM (#23759544)
But once you've accepted unchecked exceptions (and paid the cost of the having them), it just doesn't make sense to only use them only for bugs. For example, it is better to

  try:
    x = json['foo']['bar'][i]
  catch OOB:
    handle error
than to

  if not (json is a dict and
          'foo' in json and
          json['foo'] is a dict and
          ...):
    handle error
  x = json['foo']['bar'][i]
even though in the former, unchecked exceptions are used for non-bugs.
Re:Why Go's Error Handling Is Awesome by nicoburns on Tuesday July 07, 2020 @12:18PM (#23760725)
The idea is that for bugs you don't even need a try-catch (or maybe one around your entire program). And pattern matching and functions like `map` make the second case much nicer.