6 ms·
This is also one of the problems with programming with exceptions. You lean on the fact that an exception will be thrown and just propogate up until it finds so
by jerf 7y ago
This is also one of the problems with programming with exceptions. You lean on the fact that an exception will be thrown and just propogate up until it finds something, so the normal mindset of an exception-based programmer is to program for the happy-case and only vaguely think about what happens if it goes wrong. I know, I've written a lot of code in this style for many years myself.
In some cases, that's not a problem or it's even the best thing to do. However, you end up writing this way all the time in an exception-based language, which is where the problem arises.
Non-exception based languages tend to throw the problems in your face and make them something you can't ignore. Which is not fun. But it is often what you need.
- latch 7y agoThere's also the OTP model, where you have exceptions as well as a robust "something" up there. You don't have to deal with the minutiae, and the pattern (processes (aka, isolated processes) and restarts) lets you deal with known or unknown errors.
- hopia 7y agoRight, but the OTP doesn't make you deal with the exceptions upfront, only to architect your app in the way that they don't crash or infect other parts of the system.
- lonelappde 7y agoThat doesn't help you detect logic bugs, only bad input.
- xamuel 7y agoThis is especially evident in e.g. third-party Python libraries. For example, say you have a pandas dataframe with a column "foo" and you accidentally try to read column "fooo". Instead of getting a useful exception like "PandasException: Attempted to read nonexistent column 'fooo'", you get a traceback 10 layers deep, terminating in something like "pandas.hashtable.PyObjectHashTable.get_item" which ought to be totally invisible to you, the library user.
- fjp 7y agoThis is how it should be done, I'm such a fan of this page: https://www.psycopg.org/docs/errors.html https://www.psycopg.org/docs/errors.html Edit: by "this" I meant to agree with parent: Getting a useful, well defined exception is how it should be done. Psycopg2 does this very well.
- cptskippy 7y ago> the normal mindset of an exception-based programmer is to program for the happy-case and only vaguely think about what happens if it goes wrong. I'm not sure that's such a bad thing. Exception handling doesn't mean you should be handling all exceptions, just that you can recover if one does occur. If an exception is 100% relevant to what you're doing then yes absolutely handle it, or even clean up your own state before propagating the exception if you can't. But please don't catch any and all exception to suppress or obfuscate them by wrapping it in another domain specific exception.
- arcticbull 7y ago> Exception handling doesn't mean you should be handling all exceptions, just that you can recover if one does occur. You can't because you don't know where it came from so you don't know what happened, why, or if it was recoverable. You can take a stab at it, but that's it.
- cptskippy 7y ago> You can't because you don't know where it came from Maybe that's a particular language constraint? In general exceptions have a stack trace and it's evident where an exception came from. At least in my experience exceptions don't have to be handled unless or until they're disruptive. If you have a scheduler or task processor code that needs to run continuously then you're going to have robust exception handling, but not necessarily comprehensive or appropriate. For other areas of code however the exception handling isn't necessarily requisite.
- nicoburns 7y agoMy problem with exceptions, is it's generally not possible to tell which exceptions a given function might throw (especially problematic with nested dependencies). Thus even if there was a condition hat you could handle you might not know it was possible (until you hit the bug in production!) Result/Maybe types are awesome, because you just don't get unexpected runtime exceptions due to programming error. You only get them when a genuine problem occurs.
- arcticbull 7y agoExceptions are the worst because there's a hidden nested world of control flow you can't barely begin to reason about. Exceptions are a "comes-from" statement, like a "goto" but much worse.
- fjp 7y agoThis just gave me the thought... if exception stack traces came with the argument values of each method call, they would be 1000x more helpful. You wouldn't even have to attach a debugger and step through in many cases.
- Izkata 7y agoI think they do in python, or at least can be retrieved. I know they show up in the stack trace on Sentry when an unhandled exception occurs.
- fjp 7y agoInteresting, I guess they don't get spit out to the console by default. Overall Python has really good stack traces, but the hyper-dynamic nature of so many common libraries does make it tough to grok sometimes. I usually end up reaching for the PyCharm debugger which is fantastic anyway.
- fulafel 7y agoIt's probably this: https://docs.python.org/3/library/cgitb.html https://docs.python.org/3/library/cgitb.html
- deleted 7y ago[deleted]
- LessDmesg 7y agoExceptions and Maybe types aren't mutually exclusive. They should be used together. Maybe types handle variability that is expected and predictable, like a dictionary not having a certain key; exceptions handle the unexpected situations, like a file handle being closed too early. Maybes explicitly express what the programmer has foreseen, exceptions form a safety net over it. You need both in a wholesome language. That's wht even Haskell has exceptions.
- nicoburns 7y agoHaving used Rust, which almost exclusively uses Maybe types, I have to disagree. The "safety net" introduced by exceptions just hides possible errors, and causes reliability problems that would be entirely avoidable if Maybe types were used. The `?` operator makes propogating errors painless if that is what you want, but at least they're all documented so you have to make a concious chocie to pass the buck on error handling.
- renox 7y agoI don't know: if we really wanted to be 'strict' every integer operation should return a Maybe due to possible overflow, every IO operation also. That's a lot of possible error to handle! I don't like exception's invisible flow but I think that they are good for 'should never happen' errors.