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

> Maybe it's just I'm too new in go, but I feel like I'd rather have my errors taken cautiously by default, with the possibility to ignore them (catch) than having to use variable and put if statement everywhere I care about errors (which pretty much means everywhere, in my current design style).

That's what you should do.

> With errors in go, that's the reverse : errors are ignored by default.

To ignore errors in Go you need to explicitly ignore them because most functions return error.



So, most functions return two things - output data and an error. You have to assign both to something, like this:

  data, err := foo()
and go forces you to use variables somehow, or it'll give you a compile time error, so you can't just assign it and never look at it.

There are some functions which only return an error, and yes, for those, you can simply not assign the result to anything. However, in general, you should be suspicious of functions that get called that don't seem to return anything. Can they really never fail?

Note that there are linters which will warn you if you are ignoring errors (google errcheck, I don't have the URL handy).

Yes there's a lot of error checking code in Go, but that's a good thing. It's explicit, and it makes you actually think about the error case. My Go programs are WAY more robust than my programs from other languages.


Forcing you to think about your errors is a good point, there's nothing more painful than discovering that an exception is thrown on production.

I still feel it's getting in the way of the "Go allows you to be more productive" stance, though.

Also, it makes it very dangerous for people not rigorous enough that will not take enough care of their errors.

Granted, "it allows bad developers to do bad things" should not be an argument, but I wouldn't be surprised we hear in a few years of big fails that will be imputed to go error handling (with headlines like "Foo.com tragic fail was due to go forgetful position on handling errors").


Go is not intended to be a fast and loose "bang it out in an afternoon" language. If you're comfortable with the language, then you can be really productive in it, but that includes error handling. You have to handle errors, that's like 50% of programming.

I really doubt you'll see headlines like that. Why would you not see the same thing for code that doesn't handle exceptions in other languages? They're far more invisible than Go's errors, which are right there in the method signature.


> Go is not intended to be a fast and loose "bang it out in an afternoon" language

I was hoping for nothing that extreme :) But this is something I have to consider. I'm cto, in my company, and the "how much time to build that feature" is something that has a very real importance when we decide what to implement.

Ruby got us into thinking of features as a weekly thing. I can justify to spend most of the week doing in go what I would have done in a day with ruby if it allows to do things we could not do in ruby or allows to scale up (and I've already done so for resource heavy background tasks that could be parallelized, actually). Doing it in C probably would have taken more than a week. That's the extent of what I mean by "productivity" in go.

> You have to handle errors, that's like 50% of programming

Well, that's the problem. That's 50% (probably less actually, but nevermind) of go programming. The hard reality is that I care for only 10% of those errors.

If a file was supposed to be transferred to a third party server and this one is down, certainly, I want to handle error, inform user about the situation and ask her to come back later.

But if something is supposed to work 100% of the time, I don't want to have to spend time writing code that would probably just never be executed just in case an unforeseen circumstance happens. I want an exception (with some exception handling system behind that notifying me about the exception, of course, which would be a one time configuration for the whole kind of those errors) and a generic error message for the user.

That's a productivity thing too.

And indeed, most of my error handling in go are :

    if err != nil { panic( err ) }


If something is supposed to work 100% of the time, it won't have an error return value. Otherwise there's a nonzero chance it'll fail. The time you spend writing a simple "network configuration file must exist" is way less than you'd spend trying to read a stack trace when your application crashes with "filenotfound: foo.json".

If Go is 1/5th as productive as Ruby to produce the same feature, either you're very new to go and very experienced with ruby, or you're doing something drastically wrong. Obviously, experience makes a difference, but Go has a very short learning curve, so you should able to get productive relatively quickly.

I honestly don't understand how you can only care about 10% of errors. You have to think about the error case, otherwise your application is going to be a crashy, data lossy mess and no will trust it.


> The time you spend writing a simple "network configuration file must exist" is way less than you'd spend trying to read a stack trace when your application crashes with "filenotfound: foo.json".

Well, stacktrace and enforcing meaningful message error where they are generated is fine with me, but I see what you mean. Certainly, if we were to think of custom message everywhere a problem may happen, it will be easier to debug. But does it really worth it ?

> If Go is 1/5th as productive as Ruby [...]

All assertions probably apply :) I began to learn and use ruby (even if not professionally at first) before rails was a thing, so I'm quite used to it. On the contrary, I've began to use go only a few weeks ago. It took me a week during a week off (with the slow pace it implies) to learn the language and re-implement that task I thought was a perfect fit. So yeah, that's indeed very productive, and that's what I was attracted by in the first place. I also probably have done horrible mistakes that would have make this time shorter, since I'm still learning the language.

But let not underestimate ruby here, and more importantly : its ecosystem. Certainly, if I had to use only ruby standard library, it wouldn't have been that fast. But with the help of activerecord and activesupport, things suddenly get really fast.

After learning to use database/sql, I've searched for something allowing me to save time, and switched to coocood/qbs. It helped a lot (especially on managing connection pool to postgres, since I was parallilizing queries), but of course it can't compare with something that mature than activerecord.

That's not intrinsic value of the language, but it clearly affects what it means to write a feature using the language in term of time.

> I honestly don't understand how you can only care about 10% of errors

Well, I guess it depends on what kind of software you're writing. If I were to design a public facing server app, certainly, the last thing I would like to happen would be it to panic and quit. In my previous case, I was rewriting a non-destructive data processing background job, called by cron. If it fails, cron will mail me with details and try again later ; that's perfectly fine.

But let not be mistaken on what I mean by "I care about 10% of errors". It does not mean I don't want to know there were errors the rest of the time. It means that I don't want some specially crafted logic handling it to ensure data / runtime state. Having the program interrupted and a report made with error message and stacktrace is ok most of the time (for the rare occasions when it happens). Let take some actual examples.

A table in my database has an hstore field, which represents in application what we would call in go a `map[int] int`. Except that in hstore, all is string, actually. So in my go code, I have :

    key, err := strconv.Atoi( hkey )
I can understand why this function generates error, and that's a good thing, conversion to int may fail. But in my case, I know for sure I have a numeric string. So yeah, certainly, someone may introduce a bug somewhere sometime that will put a non numeric key in the hstore. But the low degree of probability for this makes me ok to deal with a message like "can't convert 'foo' to integer" with a stacktrace showing the line number when it happens (and indeed, once again, this instruction is followed by `if err != nil { panic( err ) }`).

An other example is database query functions. They all return an error, in order to relay database errors and connection to database errors. That is fine, this is information I want. But do I really need to add chunks of logic testing for those after every single query I make ? Again, having a default "raise and die" handling, with a few chunks of logic to ensure data integrity where it's at risk (on writings, for example) would be enough.


> To ignore errors in Go you need to explicitly ignore them because most functions return error.

What. If user has to write something explicitly, then it's not a default. That's pretty much the definition of "default".

Or else, C has garbage collection, you just have to write it (and you explicitly ignore proper memory management by not writing it).




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

Search: