Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I write both Go and JavaScript.

> If error isn’t typed it’s no different from “anything can throw anything anywhere in the stack”.

Errors aren't untyped. It's an interface type. Not everything returns errors anyway, they definitely can't be returned from anywhere in the stack.

Errors in Go are definitely nowhere near as amorphous as those in JS. In JS, you can take an Error object and stick additional properties on it, and then throw that. In fact, Node does that, and by extension, thousands of JS libraries generate exceptions like that.

With Go, you use errors.As(), or errors.Is(), or a little bit of dynamic casting. The type of error which a function returns may not be part of its type signature, but decent libraries usually have only one or two error types they return. Yes, I hit F12 to see the library's source to see what errors it returns... but that's just because the IDE experience with Go is so fast and nice to use.



The article talks about returning strings as errors, which I read as equivalent to (JS):

    throw 'wat'
Which doesn’t seem like a very useful interface to me. Everything can be stringly typed. But again I’m looking at this from the outside.

And by not typed, I specifically meant in the function signature. If tooling helps with that, that’s awesome.


I would suggest giving Go a chance, or at least take articles like these with a grain of salt.

Sure, Go allows you to create an error with nothing but a string message inside. The equivalent JS is something like

  throw Error('wat');
I mean… why would it stop you from doing that? You can do that in nearly any language. JS, Go, Java, C++, etc. If your language doesn’t have a way to shove an arbitrary string into an error message and return it, you’ll probably have to make it yourself.

> Which doesn’t seem like a very useful interface to me. Everything can be stringly typed. But again I’m looking at this from the outside.

What’s happening here is that your function is returning an error, but in such a way that you can’t identify that specific error from its value. If you’re a library author, you use this in two scenarios:

1. You can’t imagine a way that this specific error could be handled by the caller. (It doesn’t need a special type, because nobody will be checking for it.)

2. You expect all errors from your function to be handled the same way. (It doesn't need a special type, because you already know what to do with it.)

The way you handle errors in Go is actually quite rich, seems like it just doesn’t jive with the author’s personal preferences. Or possibly the author is using terrible libraries. Or possibly the author really hates boilerplate code (the author's complaining about “tons” of boilerplate code, but it doesn’t look like much boilerplate code to me).

If anything, my experience handling Go errors is that you might end up with rather complex error objects, with errors nested inside of other errors, multiple levels deep. You can extract a ton of information from these objects—like if there’s an I/O error, you’ll know what operation failed and the path of the file, and then inside you’ll find the wrapped I/O error without that information.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: