Normally it would be something like:
- Write terrible, terrible code
- Write slightly less bad unit tests that prove terrible code is, indeed, terrible
- Improve terrible code to be slightly less terrible
- Slightly improve terrible code with an abstraction or two. Realize entire swaths of code are actually just two objects. Refactor.
- Fix unit tests to test new refactored, elegant mess. Brag about it on a blog somewhere, impugn others.
This worked so well, until I got to the UI.
Now I have a new test tool to learn along with learning the UI widgets.
I really need test code for my test code.
But no matter, because that's not the worst of it.
The worst of it is I'm passing in a method from python into C++ wrapped in python.
This causes the debugger to (A) not respect any breakpoints whatsover and (B) not raise a python exception, but a cryptic non-helpful "C++ Runtime environment received an irregular blah dee blah" without any sort of exception.
So I've regressed all the way back to commenting out bits of code, surrounding every single statement in its own try/catch, stuff like that.
Debugging with print statements.
Truly a nightmarish hellscape.
Is it a race condition if the side you expect to lose wins every single time?
That's what I was living with today. A message indicating an object was written was beating the write() call finishing in the database.
A few days ago, I had refactored the UI to take advantage of a dispatcher object, so I'd only subscribe to my message server once, instead of opening three subscriptions. I moved the logger to a higher level object.
The logger I use in my exception handling.
I'm beating these bugs by sheer force of brain thought.
An aside, and why I like writing about what I've done in the day, I've come up with some good ideas for work.
- see if passing serialized objects instead of where the object lives makes sense - I can just act on it instead of the db row.
- write some improved unit tests that call the handlers I pass to C++ in python, so I can breakpoint them and see if anything wild happens
- write some exception handlers in their own class with some logger-specific stuff that I can reference across the project