Hacker News new | ask | show | jobs
by Buttons840 1865 days ago
I'm working with some Python that follows this error as value convention and it's awful. The code likes to catch exceptions as soon as possible and replace them with strings like "not found". Exceptions are useful things, they tell me what broke and where. Instead I get a "not found" error value, and find out that happened because the endpoint called a service that returned a "item not found" error value, and then a few layers of obscure string error values later I find out some logic did division by zero or something.

In other words, I also don't understand the hype around error values.

So, back to Python, what error value is suitable for replacing an exception? I mean, Python is flexible enough to do Go-style error values, but what does a good error value look like? Maybe I just haven't seen good error values?

If an error happens way down in the weeds and I initially return a very specific error value, do I just pass it up the stack forever? If so, how is that different than traditional exceptions? Do I replace the specific error value with more general error values as I move up the stack to higher-level code? If so, then I am throwing valuable information away and am likely to end up with something like "not found" as my error value at a the top -- not very useful.

1 comments

In Go, I would do one of: * Pass the error value up unchanged * Wrap the error inside another error * Pass a new error * Swallow the error and do something else to cope with failure

I would probably also do some error logging, capturing the state of relevant local variables, especially if it is one of those cases where "see an error" is unexpected.

Thanks for the answer. It sounds like pretty much the same thing good exception handling would do.

I suppose they're two sides of the same coin. Both can be done well or poorly.

I do resent the idea that error values are automatically better or easier to understand, because I'm dealing with some poorly done error values now and wishing for traditional exception handling.

I guess the differences I see are between "with exceptions, you can accidentally forget to handle the errors in the right place, and you end up handling them elsewhere" vs "with error values, if you forget to handle the errors, you don't handle them at all" on one side. And "with exceptions, you do't necessarily have the immediate feedback that one may come" vs "with error values, you need to choose between sticking them in an error value variable, or explicitly ignoring it" (and with Go's fondness for "you assign to a variable that is then never used? That's a compile error!" it essentially means "you either handle the error or you intentionally disregard it".

Either is fine, I think. But, don't mix both in the same codebase. And with exceptions, I would really like Common Lisp-style restartable errors, to get the flexibility I feel I have with error values.