4 ms·
That makes even less sense becasue go errors provide even less info other then a chain of messages. They might as well be lists of strings. You can maybe reassb
by tayo42 11mo ago
That makes even less sense becasue go errors provide even less info other then a chain of messages. They might as well be lists of strings. You can maybe reassbmle a call stack your self if all of the error handlers are vigalente about wrapping
- 9rx 11mo ago> That makes even less sense becasue go errors provide even less info other then a chain of messages. That doesn't make sense. Go errors provide exactly whatever information is relevant to the error. The error type is an interface for good reason. The only limiting bound on the information that can be provided is by what the computer can hold at the hardware level. > They might as well be lists of strings. If a string is all your error is, you're doing something horribly wrong. Or, at very least, are trying to shoehorn Go into scripting tasks, of which it is not ideally suited for. That's what Python is for! Python was decidedly intended for scripting. Different tools for different jobs. Go was never designed to be a scripting language. But should you, for some odd reason, find a reason to use in that that capacity, you should at least being using its exception handlers (panic/recover) to find some semblance of scripting sensibility. The features are there to use. Which does seem to be the source of your confusion. You still seem hung up on thinking that we're talking about scripting. But clearly that's not true. Like before, if we were, we'd be looking at using Go's exception handlers like a scripting language, not the patterns it uses for systems. These are very different types of software with very different needs. You cannot reasonably conflate them.
- tayo42 11mo agoChill with being condescending if you want a discussion. The error type in go is literally just a string type error interface { Error() string } That's the whole thing. So i dont know what your talking about then. The wrapped error is a list of error types. Which all include a string for display. Displaying an error is how you get that information to the user. If you implement your own error, and check it with some runtime type assertion, you have the same problem you described in python. Its a runtime check, the API your relying on in whatever library can change the error returned and your code won't work anymore. The same fragile situation you say exists in python. Now you have even less information, theres no caller info.
- 9rx 11mo ago> The error type in go is literally just a string No, like I said before, it's literally an interface. Hell, your next line even proves it. If it were a string, it would be defined as: type error string But as you've pointed out yourself, that's not its definition at all. > So i dont know what your talking about then. I guess that's what happens when you don't even have a basic understanding of programming. Errors are intended to be complex types; to capture all the relevant information that pertains to the error. https://go.dev/play/p/MhQY_6eT1Ir https://go.dev/play/p/MhQY_6eT1Ir At very least a sentinel value. If your error is just a string, you're doing something horribly wrong — or, charitably, trying to shoehorn Go into scripting tasks. But in that case you'd use Go's exception handlers, which bundles the stack trace and all alongside the string, so... However, if your workload is script in nature, why not just use Python? That's what it was designed for. Different tools for different jobs.
- hombre_fatal 11mo agoThey should have made the point about knowing where errors will happen. The cherry on top is that you always have a place to add context, but it's not the main point. In the Python example, anything can fail anywhere. Exceptions can be thrown from deep inside libraries inside libraries and there's no good way to write code that exhaustively handles errors ahead of time. Instead you get whack-a-mole at runtime. In Go, at least you know where things will fail. It's the poor man's impl of error enumeration, but you at least have it. The error that lib.foo() returned might be the dumbest error in the world (it's the string "oops") but you know lib.foo() would error, and that's more information you have ahead of time than in Python. In Rust or, idk, Elm, you can do something even better and unify all downstream errors into an exhaustive AGDT like RequestError = NetworkError(A | B | C) | StreamError(D | E) | ParseError(F | G) | FooError, where ABCDEFG are themselves downstream error types from underlying libraries/fns that the request function calls. Now the callsite of `let result = request("example.com")` can have perfect foresight into all failures.
- tayo42 11mo agoI don't disagree that exceptions in python aren't perfect and rust is probably closest of them all to getting it right (though still could be improved). I'm just saying stack traces with exceptions provide a lot of useful debugging info. IMO they're more useful then the trail of wrapped error strings in go. exceptions vs returned errors i think is a different discussion then what im getting at here.
- Orygin 11mo agoI disagree, adding context to errors provide exactly what is needed to debug the issue. If you don't have enough context it's your fault, and context will contain more useful info than a stack trace (like the user id which triggered the issue, or whatever is needed). Stack traces are reserved for crashes where you didn't handle the issue properly, so you get technical info of what broke and where, but no info on what happened and why it did fail like it did.
- tayo42 11mo ago