All programming is not created equal. There is application programming and there is framework programming for instance. Application programming tackles a specific set of problems toward a known solution. Framework programming considers the what if's and the "this should never happen but just in case".
In the world of programming, there are many application programmers and few framework programmers. This is natural. Framework programming takes a lot more thought and a lot more time up front. It is natural to lean towards application programming because customers can't appreciate the thoughtfulness of a better design or more robust solution as they are more bottom-line driven.
The dichotomy is that Magento application development is framework development. Magento core, extensions, and custom code must all work harmoniously together without explicit knowledge of each other. When code is written making assumptions about the system state or availability of objects with no consideration of the "what if" makes the process breakdown.
If you have done any extensive Magento work, you have seen this happen. Why does the enhanced analytics extension throw errors when I have this shipping extension enabled ... How could a chat extension cause address validation to fail ... and on and on.
The answer is simple ... the extensions make too many assumptions and have little to no fallback when the assumptions are not met. This is less true in Magento core but does still crop up from time to time. This is incredibly true with custom development.
We have inherited lots of code from different integrators so I can say with confidence that this is a common problem. I can't count how many times I have uttered the phrase "well they clearly didn't consider this scenario".
So how do you fix this problem ... what can be done?
The first and most important thing is to change the mindset. A developer can't look at a request and ONLY solve the very specific problem stated. They MUST consider the "what ifs". This is a cultural thing. From the top down, the entire engineering department must be on board.
Then as you develop ... you have to ask yourself questions about the code you are writing:
- How can my code gracefully fail?
- If the object(s) that I need to operate on aren't there ... what should my code do?
- What data am I assuming is available ... and what if it isn't?
- What are all of the scenarios that will happen that could cause my code to be run?
We recently wrote a pricing extension that was specifically for configurable products and it took multiple iterations to get it just right. Our original development fell short because we didn't fully consider all of the scenarios ...
- Do we handle every product type: simple, configurable, grouped, bundled?
- Have we covered every place that pricing is calculated? (add to cart versus cart updates)
- What happens if the product was added to the cart and then the underlying simple was disabled?
It takes more time on the front side to consider all of the scenarios but ultimately it takes no more time as you spend less time debugging issues on the back side ... and you don't introduce bugs into your customer's system.