DEV Community

Ethan Wells
Ethan Wells

Posted on

I read my own code from two years ago, here's what embarrassed me

Last week I needed to pull a small utility out of an old project, something I built during my first real attempt at a side product. I opened the repo expecting a quick copy paste job. Instead I spent two hours reading my own code from two years ago like it belonged to a stranger, and honestly, some of it did.

Here's what actually embarrassed me, in the order I found it.

The function that did five things and was named after one of them

I found a function called validateUser. It validated the user. It also hit the database twice, sent an email, wrote a log entry and, somewhere in the middle, quietly mutated an object that got passed in from three layers up. None of that showed up in the name. None of it showed up in a comment either, because past me apparently believed comments were for other people.

I remember writing this function. I remember feeling clever about it, because it "handled everything in one place." Two years later, one place turned out to mean one place I had to hold my breath before touching.

Twelve arguments, no types, good luck

function processOrder(id, user, items, total, discount, shipping, tax, notes, flag1, flag2, source, retry) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

I did not remember what flag1 and flag2 meant. I opened three call sites before I found one that used both, and even then I had to guess from context which was which. This was JavaScript with no TypeScript, no JSDoc, nothing. Past me trusted future me to just know. Future me did not know.

The worst part is I can reconstruct exactly why this happened. Each argument got added one at a time, over weeks, every time a new edge case showed up. Nobody sat down and designed this function. It accreted, the way a lot of bad code does, one reasonable decision at a time until the sum stopped being reasonable.

A comment that lied

// only runs once
setInterval(checkStatus, 5000)
Enter fullscreen mode Exit fullscreen mode

I stared at this for a solid minute. It was not once. It ran every five seconds, forever, and the comment was either wishful thinking from the start or true at some earlier point and never updated when the code changed underneath it. I have no way to know which, and that's the actual lesson here. A comment that goes stale is worse than no comment, because it actively lies to whoever reads it next, and the next reader was me.

Error handling that just made errors disappear

try {
  await saveToDatabase(record)
} catch (e) {}
Enter fullscreen mode Exit fullscreen mode

An empty catch block. Silent, total, no logging, no rethrow, nothing. I have genuinely no idea how many records failed to save during whatever period this ran in production. There is no way to find out now. Past me made a decision that erased its own evidence.

I think I wrote this because something was throwing an error I didn't understand at the time, and the empty catch made the error go away, which felt like fixing it. It was not fixing it. It was hiding it somewhere I would never think to look again.

Variable names that told me nothing

data, data2, tempData, finalData. Four variables, one function, and not one name that told me what any of them actually held. I had to trace the assignments line by line to figure out that data2 was the filtered version of data, and finalData was data2 after a sort I didn't understand the reason for.

I know why this happens in the moment. You're deep in a problem, the logic is fully loaded in your head, and naming things well feels like a tax on your focus. The math only stops working out once you leave the code and come back later without that context loaded anymore, which is exactly what happened here.

What actually surprised me

I expected to find bad code. What actually surprised me was how confident all of it looked. No hedging comments, no TODOs admitting a shortcut, nothing that signaled "I know this is rough." Past me wrote every one of these decisions like it was obviously correct. That confidence is what makes old code dangerous to read, because nothing in the code itself warns you where the landmines are.

I also noticed I've fixed most of these specific habits since then, not because I read a blog post about clean code, but because I got burned by each one individually, in production, at a bad time. The empty catch block cost me a debugging session I still remember. The twelve argument function cost me an afternoon just last week. Apparently that's how I actually learn things. Not from advice, from consequences.

What I'm doing differently now

Nothing dramatic. I write smaller functions, mostly because I got tired of scrolling. I never leave a catch block empty, even if all it does is log and rethrow. I stopped naming things data2. None of this required a framework or a philosophy, just enough scar tissue to remember the pain the next time I was tempted to take the shortcut.

I'll probably read this exact code again in another two years and find something in what I'm writing right now that makes me wince. That's fine. If it didn't, it would mean I'd stopped getting better, and an embarrassing function beats a stalled one every time.

Top comments (0)