Force it to Fail: To-Do Lists for a Disorganized Developer

I am not a note-taker. I’ve tried for years to become one, using all the recommended note-taking apps and trying to keep helpful to-do lists. It never works. I end up with a pile of words that will never be revisited.

What does work for me, though, is making the items on my to-do list as difficult to ignore as possible. Since most of my work is just writing code, that’s easy to do. Here, I’ll revisit how and why I intentionally scatter errors and fail tests throughout the code I’m actively developing.

throw new NotImplementedException();

I love C#’s NotImplementedException. It can stand for: “I’ll get to it later.” Or maybe it means, “I will not get to it ever, and if you want to use this function, well, that’s your problem.” They can also act as little trail markers that you can follow from start to finish. In any sufficiently-organized code base, implementing a new feature will require a handful of new components or functions across the various layers of your application.

Define your functions, toss in your exceptions as you go, and clear them away one by one. You’ve just made a to-do list for all the expected parts of your task. Every item must on the list must be addressed (or, intentionally ignored) before you can write system tests or do any manual testing.

expect(“handles this really weird edge case”).toEqual(“not yet!!”);

While developing your feature, it’s very common to suddenly think of an unexpected edge case. It’s also very easy to let this completely derail you. To stay on track while also making it a priority to revisit these edge cases, I like to add failing unit tests as placeholders to capture these little problems that pop up unexpectedly. This allows us to at least get an initial happy path implementation working end to end. And if, during the thrill of getting your initial implementation to finally work, you forget to address the edge case, you’ll have a failing test in CI when you go to publish your code for review as a reminder of all the extra error handling that remains.

const IMPORTANT_ERROR_MESSAGE = “reviewers, please send help”;

Usually, you’ll want an extra opinion on the look and feel of what you implement, the copy that you use throughout the UI, or the allowed values for some input. But sometimes, you’ll need someone’s explicit approval. In situations like this, I like putting little cries for help in the code. The copy “reviews, please send help” is very clearly wrong, and demands more attention than an almost correct or plausibly correct value.

The important thing that ties these examples together is that the technique makes it impossible to not come back and address them later. Manufacturing failure cases by throwing exceptions or adding failing test cases or wiring up blatantly incorrect data forces you to come back and address unresolved issues. In contrast, standard to-do lists only do so if you’re an organized person by nature.


Join the conversation

Your email address will not be published. Required fields are marked *