News for hackers. Stuff that matters.
Re:Conc: Better Structured Concurrency for Go by vbezhenar on Wednesday January 11, 2023 @09:16PM (#34348253)
I started to write Go recently and I very much prefer panics to errors. For example in web apps. Panic produces nice stack trace. Panic bubbles automatically, I can reduce amount of code significantly. Errors are awful and panics allow to write code without losing sanity. It's like good old exceptions. And if I really need it, I can catch panic and act as needed, e.g. return HTTP code or whatever.
Re:Conc: Better Structured Concurrency for Go by xyzzy_plugh on Wednesday January 11, 2023 @10:08PM (#34348672)
You should rarely reach for panic. Panics are not like exceptions, really. It's very frowned upon for panics to pass API boundaries. Use errors always, unless the state of the world is irrecoverably broken.

It's difficult to come up with examples of when this may be the case. Often it's a "you're holding it wrong" kind of thing. For example, a common idiom is wrapping something like

    func Parse(s string) (Foo, error)
to be usable in contexts where error handling isn't possible, such as variable initialization.

    func Must(f Foo, err error) Foo {
        if err != nil {
            panic(err)
        }
        return f
    }
which could be used at the global level like so:

    var someFoo = Must(Parse("hey"))
This is acceptable because this code is static and will either panic at boot always or never.
Re:Conc: Better Structured Concurrency for Go by vbezhenar on Wednesday January 11, 2023 @10:25PM (#34348790)
Errors don't have stack traces so they're unusable. And I see nothing wrong with handling panics. They're the same exceptions. I got SQL exception, I panic, handler catches panic, logs its stacktrace and returns HTTP 500. Awesome and no boring error handling.
Re:Conc: Better Structured Concurrency for Go by bit_flipper on Wednesday January 11, 2023 @11:31PM (#34349216)
It's fine to dislike Go's philosophy on error handling, but in order to save you and your co-workers a lot of headache down the road, I'd recommend you just use another language. This is not something you want to do in Go and very few folks who program in Go would be happy to work with that style of code.

In case you actually are interested in Go's take on stack traces: You are intended to annotate your errors so you can build your own stack traces with whatever information you want. This leads to better error messages because additional context (values of things) can be logged with your custom stack trace.

Re:Conc: Better Structured Concurrency for Go by vbezhenar on Thursday January 12, 2023 @12:18AM (#34349517)
Do you suggest me to annotate my errors with "file:line" strings? Do you suggest me to grep source files with error messages to deduce stack trace? Because that's what I'm doing right now when I have to deal with stacktrace-less errors and it's not pleasant.
Re:Conc: Better Structured Concurrency for Go by philosopher1234 on Thursday January 12, 2023 @01:22AM (#34349908)
The idea is you `fmt.Errorf("invalid foo, given '%v' important argument: %w", arg, err)` and you end up with errors like:

    http GET /abc: start DB: run migration COOL_MIGRATION: invalid foo, given 'bar' important argument: file not exist
If done well, you might be able to fully diagnose the bug just by reading the error, since it may include every bit of relevant context. If not, you can grep for the original error substrings to find the relevant code.

The point is that these aren't just Xs on a map telling you where something went wrong, they're supposed to be meaningful descriptions of why something went wrong.

Re:Conc: Better Structured Concurrency for Go by tommiegannert on Thursday January 12, 2023 @03:56AM (#34350870)
> Do you suggest me to grep source files with error messages to deduce stack trace

Yes, that's common. Perhaps a gopls search engine for error messages would be useful?

Re:Conc: Better Structured Concurrency for Go by atombender on Thursday January 12, 2023 @05:37PM (#34361249)
In the sense that errors are values, you should not normally need to hunt for the origin of errors, and so stack traces should unnecessary.

Many errors don't need metadata. For example, io.EOF signaling the end of a stream is a normal condition. But there are those "true" errors which are unexpected conditions indicative of a bug or a scenario that should be handled differently. To make those easier to find, you can annotate the error values to make it clear what the origin was. This is why there's now a well-established convention to wrap with contextual descriptions at every point in the chain.

In about 8 years of working full-time with Go, the number of situations where I've struggled to hunt down the source of an error value is pretty close to zero. Not zero, but close.