My take on throwing exceptions for controlling the code flow
Who should read this: Any one associated with any kind of software development.
Read time: ~ 2-3Min
Some context for this write up : API(web or otherwise) can result an error in turns of "Exception"(Validation or Unhandled) or through result of API end point. Recently I had a task where my job was to create a module to standardize the errors(Validation or Unhandled) returned from API, so I handled both uses (Exceptions and handled error returned from API), in my module but `I did not document the use case where how Developer can throw a Validation Error Exception out of API which will be handled by common module`
Why I did not document it:
Well, my code went through two reviewer who are amazing developers and highly skilled at their job and both said, "Controlling the code flow through exception is not encouraged and shouldn't be done and exceptions are expensive".
There is one more reason, on which I agreed but that I cannot reveal the details without giving you insight on project, which I can't do.
Recommended by LinkedIn
My philosophy on it:
I think we read something somewhere(book/articles) and it sticks in our head as - this is the best practice, and this is how things should be done because someone very credible said that in so and so article/book. Well, I disagree - The credible author of best practice cannot possibly consider all the possible use cases around subject he is writing on. Hence no one should take it as scripting on stone which cannot be modified.
Well seems like throwing exception is not a good thing is for sure a scripting on stone:)
What are arguments from the one who follows this stone scripting:
- Throwing exception is expensive - Well, yes but do we know expensive? after all its a relative term. So to put things into prospective according to a SO post - "It took the program below 29914 milliseconds to process one million exceptions, which amounts to 33 exceptions per millisecond. That is fast enough to make exceptions a viable alternative to return codes for most situations". I seen the example for this calculation and I see 4-5 stack frames in there but even for higher stack frames, It will be around ~15 exception/ms and CPU usages was under control as well. Be diligent it was very low grade machine not even marginally closer to production servers. So then question is 15-30 exception/ms is expensive for you? Point is always test in your environment and see it for yourself.
- Exceptions for code flow management is bad - I agree, If you check some property of exception and then make decision to do one thing or other is bad, we should use error code for that. But if we want say we are done here and no more processing can be done from now on- throwing exception is expression exactly denotes so. Otherwise each and every method in call stack chain will have check for error codes. Another point here is that some times when you realize that this request is bad, you are at certain place where you don't have liberty to return error message because of method return type. Throwing exception becomes an easy viable option in this case.
Most of the validation library in the .net ecosystem throws exception. If you ever worked in .net web ecosystem, you might have seen this namespace in your code - System.ComponentModel.DataAnnotations, Well this work totally on throwing exceptions. If you ever written test cases, you might have come across FluentValidation (If not check it out - its amazing) - It completely works on Exception throwing.
Conclusion: Throwing exception with appropriate message to say your request is denied is communication expression, don't suppress it because of some stone scripting. This also doesn't mean that you generate exception in good flow to make decisions - be diligent that exception generates page faults which results in cache miss(hotspots in your profilers) which in will indeed result in slow I/O from heap(Read other article on my profile to see how).
Don't take my word as stone scripting:)