Hacker News new | past | comments | ask | show | jobs | submit login

>The verbosity of Go’s error handling has been much-maligned. It’s simple and explicit, but every call to a function that may fail takes an additional three lines of code to handle the error

Putting error nil checks into a function is an anti-pattern in Go. There is no need to worry about the LOC count of your error checking code.

inb4 this ends up on pcj




> Putting error nil checks into a function is an anti-pattern in Go.

I assume you mean into a helper function like I've done with check()? If so, I agree with you for normal "production" Go code. But for simple throw-away scripts you don't want half your code littered with error handling, when you could just throw a stack trace.

> There is no need to worry about the LOC count of your error checking code.

Well, it means some functions are more than half error handling, obscuring the guts of what a function actually does. Even the Go language designers agree that Go's error handling is too verbose, hence proposals like this from Russ Cox: https://go.googlesource.com/proposal/+/master/design/go2draf... (there are many other proposals, some from the Go team)

> inb4 this ends up on pcj

im not shur wut pcj meenz


After they introduced generics I immediately wrote a generic Must function that returns the thing or panics.

There’s plenty of (pre generics) Must functions in the std lib that fo this.


agreed. when I see people talking about LOC my eyes roll. its verbose for a reason, the language designers WANT YOU to pay attention to the errors, not ignore them.


Being verbose and needlessly repetitive is indeed something they wanted, but it doesn't mean it's a good solution.

If something is too verbose and repetitive your brain will learn to skim over it, making it lose effectiveness while increasing the risk for bugs.


I think the ultimate question for me is, does increased tedium demand/imply/require "attention", or does it just create a new opportunity for mistake? If devs are so frequently writing these "check()" style functions, are they paying attention to or ignoring errors?


The language designers aren't the boss of you. Just because they want something doesn't mean you have to do it.


That's exactly why every other language took the wiser decision of actually having runtime errors.

To force you to pay attention to them before your application state went into an unknown configuration, thus making it nearly impossible to troubleshoot or even pretend to be deterministic.

I still have no idea how any programmer thinks this is OK. Nondeterminism and unknown/un-considered application state are literally the source of all bugs. I much prefer (and honestly believe it makes a ton more sense) to do what Erlang/Elixir does, which is to fail, log, and immediately restart the process (which only takes a few cycles due to the immutability-all-the-way-down design).

If you hit my Phoenix application with a million requests in 2 seconds and each throws a 500 error, my webserver will keep chugging along, while every other technology's webserver will quickly exhaust its pool of ready-to-go webserver processes and fall over like a nun on a bender.


I don't really know how to take comments like this.

I work on a pipeline that processes millions of events per day in a pipeline that contains two pretty busy Go programs. One has an embedded Javascript engine and does all kinds of pattern matching and string manipulation. The other does a ton of database read/write and some crypto-calculations to do data integrity for us.

Millions of events. Per day. Never a panic in production.

It is easily possible to write deterministic, highly performant, and durable applications in Go.


> millions of events per day

I was talking about millions of events per every couple of seconds, not per day. A million events per day can be accomplished with just 11 per second, btw; a very... achievable number.

WhatsApp, which is built on OTP, handled 64 billion messages in a day. Averaging out to 744,000 a second. Almost 10 years ago. (Granted, also on 8000 cores. But thanks to the concurrency...)

https://www.businessinsider.com/whatsapp-64-billion-messages...


> One has an embedded Javascript engine and does all kinds of pattern matching and string manipulation.

Why did you decide to use an embedded JavaScript engine instead of pure go?


> every other technology's webserver will quickly exhaust its pool of ready-to-go webserver processes and fall over like a nun on a bender

Most other technologies don't use one process per request, but instead have a single server process which handles all exceptions that come out of a request by returning 500 without crashing the server.


You can absolutely do this in Go. In a webserver you panic and recover your goroutines for 500’s or other failures that you deem invalid states.

There’s a qualitative difference between what we call 500 errors or 400 errors and it’s a good thing to handle the former by throwing exceptions or panicing and the latter with normal program flow and error values.

Errors that you can sensibility handle and display are part of your domain logic, just values and functions. They should be handled and contextualised right there at the site they come up.

Errors that represent invalid program states should be thrown as far as possible and handled at the edge.


> Putting error nil checks into a function is an anti-pattern in Go.

What should you do instead?


You may have misread this. The OP means "extracting error nil checks into a function is an anti-pattern", not "your functions should not contain error handling".


I see, that makes more sense, thanks :)




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: