Most of my bugs started with a word, not with code
My app went public on the App Store and Google Play on July 13 and I've rebuilt it more times than I'd like to admit. When I look at the list of fixes, most of my bugs started with a word, not with code. In the last epi
My app went public on the App Store and Google Play on July 13 and I've rebuilt it more times than I'd like to admit. When I look at the list of fixes, most of my bugs started with a word, not with code.
In the last episode I told how the colors of my first prompt survived while five languages turned into four different places to keep in sync. This one is about how the app changed between the first sketch and today and about the fixes that taught me something.
The model that kept changing
Some parts of the app changed shape three or four times:
- "I'd like to go". In January it was one of three states of an event. In February the states became times: now, in one hour, tonight. In April "I'd like to go" was removed. In June it came back as its own feature, the Wish. Later it got its final name: "Vorrei", "I would like".
- Login. Google, Apple and Microsoft in January. Google and Apple a week later. Then, in March, a phone number with a code, which fits an app built around the contacts you already have.
- The map. In February it was a web map inside a WebView. Two weeks later it was a custom widget drawing OpenStreetMap tiles directly.
- Onboarding. Four pages with six animations in July. Two pages on September 1. One screen with a single "Create" button on September 10.
- Ads. There was a small banner at launch. I removed it at the end of August because the benefit was close to zero. Removing it took more work than adding it because in my case Google Play kept blocking updates while an older build with ads was still active.
At the end of August I rebuilt the whole interface. The screen to create an event went from 2,895 lines to 464. The code worked. People got lost: too many steps, too many choices, too much to read. To be honest it's the most expensive lesson of the whole project and I'll come back to it in the last episode.
Bugs that started with a word
"In 1 hour" created the event now. In May, in the Italian version, picking "In 1 hour" created an event starting immediately. The code decided the start time by checking the text of the button for English words like "now" or "1h". In Italian the button said "Tra 1 ora": nothing matched and the code fell back to "now". The fix was to map every visible label to a stable internal code first and compute from the code.
Four months later, the same bug came back in Romanian. In September a native review improved the Romanian translation: "Peste 1 orΔ" became "Peste o orΔ", which is more natural. Somewhere a piece of logic still depended on that label and the event started immediately again. The note I wrote that day: a translated label is a value, not a text. Translating it is a code change when something depends on it.
A sentence in the app wasn't true. One screen said the address book never leaves the phone. To match contacts, something derived from the numbers does leave it. Nobody had lied on purpose: the sentence had been written before the feature changed. I rewrote five texts that day and the lesson surprised me. Searching for words like "never" or "always" didn't find the false sentences. Only reading each one against what the code does found them.
The website promised more than the app did. The site said the invite "works even without the app". The invite page said "to reply, you need the app". Both were true. Read together they made a promise the app didn't keep. The sentence now is: anyone with the link sees the event; to reply, they install the app.
Bugs that started somewhere else
Not everything was about words:
- Location check on future events. Creating "Saturday at my place" while at home made the app think you had checked in. When you left the house, it closed the event, with all the replies. Found in September.
- A timer that read too much. The home screen refreshed every 4 seconds and re-synced data at every tick, which by my estimate meant around 900 database reads per hour for each user. On a free tier that's the fastest way to a bill. Today it refreshes about every minute and a half. With a slow network it keeps showing the last good result instead of emptying the map.
- "Tomorrow" that wasn't tomorrow. In October, checking the code against daylight saving time, I found two places where "tomorrow" was computed as now plus 24 hours. On the day the clocks change a day lasts 23 or 25 hours, which can put the event on the wrong day. Now the date is built from the calendar parts (year, month, day plus one). The fix goes out with the next update.
-
A space at the end of a name. A settings collection created by hand in the console was called
app_configwith a trailing space. The games didn't start and the error made no sense until I copied the name character by character. - A push that opened an empty page. The notification carried the event's ID instead of its full path. Tapping it opened a blank event.
Some fixes I already described in my first article, the one about how events expire.
What I took from it
- Never put logic on a text the user can read. Decide it before the second language arrives.
- When you change a feature, reread every sentence that describes it, in the app and on the website, against what the code does now.
- The most expensive bug is a confusing screen. It doesn't crash. People just leave.
- Write down why you removed something. Removing is often harder than adding.
Next episode: working with several AIs and the rules I had to write because they all remember things wrong.
I'm building orbiTome solo, with FlutterFlow and Firebase. More at orbitome.com.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.