DEV Community 👩‍💻👨‍💻

Discussion on: Five Levels of Error Handling in Both Python and JavaScript

thorstenhirsch profile image
Thorsten Hirsch

Great article about error handling! I try to comprehend all the levels and why you ordered them the way you did. Well, I don't know using pattern matching for error handling, so let's just skip that for a moment. I'm a big fan of RxJS and and appreciate the pipelined way of error handling very much.

However I don't understand why you put the return value concept on a higher level than the try/catch concept. I learned try/catch first (Java) and later had to implement a return based error handling in C. It felt tedious and less powerful than the try/catch of Java. Was it the specific implementation...? Maybe. It definitely felt easier to "forward" errors in layers that should not do error-handling without the risk of forgetting errors, because all these functions are marked with "throws XyException", which at some point has to be handled. So I would rate the try/catch concept higher than the return value concept.

jesterxl profile image
Jesse Warden Author • Edited on


Try/catch/throw has 3 different flows in your code. Either your code works, fails, or it breaks. Using return values, your code never breaks; it's simply a return value that states the function didn't work. You don't have to wrap your code with try catch in case "something in there" explodes. This is more complicated in things like JavaScript and Python ThreadPool where async things break and try/catch suddenly don't cover everything. Also, did you remember global error handling so your Docker container can gracefully clean up and fail and K8 can restart? Ugh.

Go's style, or RxJS's pipelines make it really simple: "All this works, and if it doesn't, we'll give you an error and tell you why". No need for try/catch, or the bravery NOT to use try/catch (I'm ignoring Go's panics for now). First, I say "really simple", but not having try/catch is a huge change for people. Secondly, you're asking many are used to OOP based languages to no longer use class; they'll question how they abstract and organize things? Third, you're encouraging returning values. Many OOP languages have side effects and Noop's galore; you call all kinds of functions or class methods that return no value and operate on internal state or send events elsewhere. You never use the return keyword. However, if you're willing to learn this new style, your life is simplified because you no longer have to remember 2 types of code execution: normal and exceptions. Now, it's just "function return values".

Also, my article is Functional Programming biased, specifically typed. If you create pure functions, then Go's style works great because your code is predictable. Unlike an impure function in JavaScript or Python, which works, doesn't work, or throws an exception. Now you have 2 instead of 3. Testing is easier, too. Also, your function can no longer break other functions you use it in. Also, it can no longer break your program; it can't throw or raise exceptions, so it's safe. That's huge. You just negated the need for a throwable keyword in Java. Writing functions that either work or not, can't break your program, are easier to test, and you never need to use try/catch again is wonderful. Now, getting this full benefit in dynamic languages like JavaScript and Python is hard since they don't have types, but it's still a step in a more predictable code direction.