Software engineers are supposingly the worst kind of engineer because its somehow too convenient environment allow people to abuse trial error then retry approach too often up to a point they lose sense of the structure of the engine they are making. You might think I am selling myself and peers for cheap but hear me out: in other industries, you have to calculate, imagine and foreseen a lot of use cases during the implementation phase before give your output a try to keep the cost and the risk as low as possible. Meanwhile in software engineering, for a Frontend dev for example, you can test an unlimited amounts of times and it would take about 2-5 seconds. To live in this env is like living on Mars where the gravity is way less than when on Earth and you feel like Superman. The problem is: once you live in Mars for too long, you will forget how to walk on Earth. The same thing happens to software engineers, they forget how to make a good structure, calculate the cost of a feature, imagine use cases and foresee the risks because they have always been try-error-retrying.

The reliance on this approach will create a time bomb in the engine. For example, if a junior/heartless dev was assigned to shipping a module, if he tried hist best he can manage to make it work, even make it fast and god forbid even make it beautiful.. up to a certain point. The thing is it would require much bigger effort if not impossible to go beyond that point. After this point, when someone else needs to extend / maintain that existing module or the module start to have intermittent bugs , trial and error would be exhaustive because there is just simply too much to try out on a codebase that had already been implemented so randomly before that. And folks, that why you have to be well aware of the structure of what you are making, someone might think I am about to vote for premature optimization, but in fact the opposite - premature optimization is a sign of you are not fully aware of the structure which lead you to a wrong assumption on what is flexible and what’s not. You can copy and paste or insert magical setTimeout to solve some race condition, just make sure that you ARE WELL AWARE OF THAT and have an good enough way to communicate that with your peers.

About how to debug and fix bug with less luck required, next time I suggest that you decompose the unexpected behaviours into smaller, atomic steps. Give them expected output and check from top to bottom until you found something is quite not right. If the reproduction is not easy, consider make it easy so that you have a better dev environment. I hardly see something that is impossible to mock, but I seen a lot of cases where it is just so cumbersome that people are convinced to do a blind fix - which even when worked, create a myth in the app so they warn other people better not touch it anymore. That’s just fecked up.