Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2025-06-01 20:01
Error'd: Forsooth
Elte Hupkes"Some weird Android behavior has my phone disconnectingfrom WiFi until I open it back up in the morning,triggering some backups. Unfortunately, WhatsApp Backupisn't a morning person."
CodeSOD: Maximally Zero
Today's anonymous submitter found some Java code which finds the largest value in a quartet of floats. Now, the code is quite old, so it actually predates varargs in Java. That doesn't excuse any of what you're about to see.
CodeSOD: Do a Flip
Kendall found some recently written code, and had to wonder, "Who wrote this crap?" Much to Kendall's disappointment, source control knew who wrote it: Kendall.
CodeSOD: Exceptional Control
Sebastian started a new job recently. Like a lot of "I started a new job," stories, this one starts with a 1,000 line class definition. What's notable about this one, however, is that most of that code is error handling. Now, you might think to yourself, "well, there's nothing inherently wrong with loads of error handling, if the problem calls for it.This code is getting posted here. Do you think the problem calls for it?
Representative Line: Tern on the Error Message
When discussing ternaries, we also have to discuss readability. While short and concise, they're in some ways too compact. But don't worry, Mark's co-worker has a wonderful simplification to ternaries. This representative line is a pattern used throughout the codebase.
Error'd: Epic
"Grocery stores are going too far with their energy foods" charged Tim DG. "I was just looking for some salads to go with my BBQ,"he complained. "I'm not sure they sell what I'm looking for."I've seen what your kin put in their Huzarensaladen, Tim,so I'm not entirely surprised about the Duracells.
CodeSOD: Stored Procedures are Better
We all know that building SQL queries via string concatenation, and then sending them to the database, is just begging for fragile code and SQL injection attacks. But, what if the bad part is the "sending them to the database" part? Has anyone ever thought about that?Kris's predecessor has.
CodeSOD: Under the Sheets
Many years ago, Sam was obeying Remy's Law of Requirements Gathering ("No matter what your requirements actually say, what your users want is Excel") and was working on a web-based spreadsheet and form application.The code is not good, and involves a great deal of reinvented wheels. It is, for example, Java based, but instead of using any of the standard Java web containers for hosting their code, they wrote their own. It's like Java Servlets, but also is utterly unlike them in important and surprising ways. It supports JSP for views, but also has just enough surprises that it breaks new developers.But let's just look at how it handles form data:
CodeSOD: Disable This
One of the first things anyone learns about object oriented programming is the power of inheritance and overriding functions. Isn't it great that you can extend or modify the implementation of a function in your derived classes? Don't you wish you could just do that for every function? Aash's co-worker certainly does.
README
One of the clients for Rudolf's company was getting furious with them. The dev team was in constant firefighting mode. No new features ever shipped, because the code-base was too fragile to add new features to without breaking something else. What few tests existed were broken. Anyone put on the project burned out and fled in months, sometimes weeks, and rarely after only a few days.Rudolf wasn't too pleased when management parachuted him into the project to save it. But when he pulled the code and started poking around, it looked bad but not unsalvageable. The first thing he noticed is that, when following the instructions in the README, he couldn't build and run the application. Or maybe he wasn't following the instructions in the README, because the README was a confusing and incoherent mess, which included snippets from unresolved merges. Rudolf's first few days on the project were spent just getting it building and running locally, then updating the README. Once that was done, he started in on fixing the broken tests. There was a lot of work to be done, but it was all doable work. Rudolf could lay out a plan of how to get the project back on track and start delivering new features.It's about then that Steve, the product owner, called Rudolf in to his office. "What the hell do you think you're doing?"Rudolf blinked. "Um... what I was asked to do?""Three days and you just commit a README update? A couple of unit tests?""Well, it was out of date and meant I couldn't-""Our client is crazy about their business," Steve said. "Not about READMEs. Not about unit tests. None of that actually helps their business."Rudolf bit back a "well, actually," while Steve ranted."Next thing you're going to tell me is that we should waste time on refactoring, like everybody else did. Time is money, time is new features, and new features are money!"Suddenly, Rudolf realized that the reason the project had such a high burnout rate had nothing to do with the code itself. And while Rudolf could fix the code, he couldn't fix Steve. So, he did what everyone else had done: kept his head down and struggled through for a few months, and kept poking his manager to get him onto another project. In the meantime, he made this code slightly better for the next person, despite Steve's ranting. Rudolf eventually moved on, and Steve told everyone he was the worst developer that had ever touched the project.The customer continued to be unhappy. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Error'd: The State of the Arts
Daniel D. humblebrags that he can spell."Ordering is easy, but alphabet is hard. Anyway for this developerit was. Can anyone spot which sorting algo they used?"Next he'll probablyrub it in that he can actually read unlike the TDWTF staff.I guess we'll never know.
Representative Line: Tern on the Flames
There's nothing inherently wrong with the ternary operator. It's just the kind of thing that gets abused.Now, we all know how it should be used. We frequently would write something like this:
CodeSOD: Currency Format
"Dark Horse" inherited some PHP code. They had a hundred lines to submit, but only sent in a dozen- which is fine, as the dozen lines tell us what the other hundred look like.
CodeSOD: Required Requirements
Sean was supporting a web application which, as many do, had required form fields for the user to fill out. The team wanted to ensure that the required fields were marked by an "*", as you do. Now, there are a lot of ways to potentially accomplish the goal, especially given that the forms are static and the fields are known well ahead of time.The obvious answer is just including the asterisk directly in the HTML: <label for="myInput">My Input(*)</label>: <input...>. But what if the field requirements change! You'll need to update every field label, potentially. So someone hit upon the "brillant" idea of tracking the names of the fields and their validation requirements in the database. That way, they could output that information when they rendered the page.Now, again, an obvious solution might be to output it directly into the rendered HTML. But someone decided that they should, instead, use a CSS class to mark it. Not a bad call, honestly! You could style your input.required fields, and even use the ::before or ::after pseudoelements to inject your "*". And if that's what they'd done, we wouldn't be talking about this. But that's not what they did.
CodeSOD: Catch or Else
Today's anonymous submitter asks a question: "How do you imagine the rest of the codebase to be like?"Well, let's look at this snippet of TypeScript and think about it:
Error'd: Planing ahead
Yes, the title misspelling was an intentional attempt at punnery.It's a compulsion, I'm sorry.I might have advisedAdam R. not to try to plan flights 4 years in advance, if asked. But he didn't ask, and so he discovered this. I'll let Adam explain.
CodeSOD: Location Chooser
Today's anonymous submitter inherited an application with a huge list of bugs and feature requests for missing features. While tracking down a bug, our submitter learned a lot about why "Allow additional stores to be viewable in the store selector," was an unimplemented feature.
CodeSOD: Yes, No, NO NO NO NO
Mike was doing work for a mobile services provider. He found this in their code:
CodeSOD: Mailing it In
Dan B is working on software which interacts with a bank. We'll get the REAL WTF out of the way right at the top: "The bank has requested that we send them an email containing the total of all the transactions..."Yes, core financial business functions being handled over email. I imagine some readers are probably thinking about drinking something stronger than coffee at the thought of it. A lot of readers, on the other hand, are already onto something stronger than coffee and going, "Oh, yeah, seen that before. Hell, I'm pretty sure that EDI explicitly supports email as a delivery mechanism."Let's dig into Dan's more specific challenge. The program he was supporting needed to take an input from their backend- a mainframe style, flat-file with fixed-width fields, and convert it into the format the bank wanted. Their input file tracked the value of each transaction as a zero-padded number in cents. E.g., a ten dollar transaction would be "0001000". The bank wanted a roll-up of all the line items, where the currency was represented as dollars and cents, e.g. "10.00". The email alert that needed to go out simply needed to be a summary of the file processed.Now, there's an obvious way to do this, even when we're worried about things like floating point rounding errors. There's also a wrong way to do this. Let's look at that one.
CodeSOD: An Exceptional Junior
When "dragoncoder047" was but a junior developer, without very much experience at all, they were tasked with building error handling in a Python Flask web application.Now, they were a junior, and tossed into the problem without much preparation, or much supervision, and just told to "make it work". So they did. With this disaster:
Error'd: Too Spicy For My Hat
My plate has been full this week, but not as full as Walter's!"Maybe hold the cheese?" suggestsWalter T. regarding a pepper and steak grinder."Seen at Reading (MA) House of Pizza on Jul 24 2024." If youdecide to search around to try to understand the different names for this kind of sandwich, you willundoubtedly discover someone trying to claim that really, the hoagie is a different sandwich from a submarine,which is different from a grinder and so on. They are wrong,and this is how we know: if they truly were different kinds of sandwiches, then somewhere on this planet would be a shop selling examples of each of the differentvariants for your dining pleasure. There is not*. Q.E.D any consistent regional variation in bread choice, or dressing, or fillings, is simplythat: a regional variation of the same thing, not an entirelydifferent category.
CodeSOD: Reflections on Privacy
Jaco's team had a problems with making an embedded web server shut down properly. Something about the shutdown process was deadlocking, so one of their "ninja Yoda coders" rockstarred their way to a solution.
CodeSOD: How to Validate an IP Address
Andy has some concerns about future proofing. In this case, he sends us some C# code that's supposed to validate an IP address.
NPath Complexity
We're not going to look at code today, and instead, we're going to talk about a code metric. Specifically, "NPath complexity".NPath complexity is a good metric to track, and many static analyzers will do it. Formally written, it's defined: "The NPath complexity of a method is the number of acyclic execution paths through that method." Or, more simply, not counting loop iterations, this is how many branches you have in a single method.Obviously, for simplicity's sake, this number should be small. Hell, ideally, it should be small enough that you can count it on your fingers. Ideally, small enough that you can count it on your fingers after attempting to drunkenly operate a bandsaw with no training.But a lot of code doesn't hit that threshold.Nikola's team decided it was time to start tracking some of those metrics. The tool they were using set the default threshold where it complains at 200- 200 different code paths in a single function.Nikola didn't provide the code. But she did provide a telling snippet from the report:
CodeSOD: Serial Properties
Jan wrote some code that set a property, and a few lines later had to write code to read that value- and the compiler complained. Which is what drew his attention to this C# code:
Error'd: Pennies From Heaven
Adrian M.lit up this blooper for us. "Apparently Siemens Mobility wasn't satisfied that a mere95-year copyright term would be enough for the brochureabout their m60-series traffic light controller. I hopeI won't have to wait until 2029 for a green light."See for yourself here.
CodeSOD: False True is True False
Languages which do type-coercion are generally setting users up for failure. At some point, you'll make some assumption about your inputs, and then type-coercion kicks in and changes what you expect. We see this all the time in JavaScript, and of course, in PHP. PHP booleans, for example, can surprise you: 0 is false, which is a common enough assumption, but so is "0"- the string zero. As are empty arrays.But what if you wanted more control over it? Peter sends us this PHP he found:
CodeSOD: Sanitary Paths
When accepting user input for things like, say, accessing the filesystem, you need to do some validation. Bad or inappropriate characters could lead to surprises that no one is going to like.So when Christian first spotted this C# method called SanitizePath, he didn't think much of it. But then he looked at the implementation...
CodeSOD: Prefixual
Maciek has the distinct pleasure of working on Dynamics Ax, and ERP system. Like every other ERP system, it's endlessly customizable, and scriptable. In this case, scriptable in a custom language called "X++".While it's probably entirely possible to write good code under these circumstances, it's not an environment conducive to that. And that's how Maciek inherited this method:
CodeSOD: Uniquely Enough Identifiers
Running and hosting a database is expensive. Not only do you need the server for it (even if you rent in the cloud), you also need the expertise to administer it. And that's why Lucas ended up working on an application which used Google Sheets as its database.Now, this was an application used by a marketing team to create new marketing campaigns, so Google Sheets wasn't the worst choice made in the entire process. With only a handful of users and dozens of records, it was fine. You didn't need to put a huge amount of effort or expertise into it- at least, that's what management thought.The application didn't get the expertise it needed to work well, but "working badly" was sufficient for most cases.Since each row needed a unique identifier, here is how they handled that:
Error'd: Watching the Days
This week, we saw some unexpected results in UK politics.Nothing was more unexpected than the dark-horse results thatRichard and a few anonymice remarked on."A glorious victory for the Undefined party!" crowed Richard"The UK general election has seen a surge of support for minor parties."
Best of…: Classic WTF: Cluster#$%&
Best of…: Classic WTF: Python Charmer
Best of…: Classic WTF: What's in a Name?
Best of…: Classic WTF: XML Anybody?
Error'd: That Movie with Whatsisname
This week's special edition is a series of Error'ds specificallydealing with trains, which geeks are for some reason especiallytaken with. It should go without saying that the reason these are predominantly from Europe is not an indication their infosystems are especially bad, but rather as we all know, US passenger trainsare so little used that there is far less opportunity to discover any wtfs.This entry byRobert G. requires explanation. London North East Rail hasa novel (six years old now but still new to me) point-of-use displayof seat reservations. In my train experience, a reserved seat ticketonly identifies a certain car but not a specific seat, so this ispretty slick. On LNER, if you don't have a seat reservation but you're traveling in the specified class, you can take any seat labelled"Available" but you'll need to vacate it at the "until XXX" station.The two rows in Robert's fuzzy image read "Current" and "Next",which should help to understand what has happened here. The two red lights indicate "Reservations". As Robert puts it,"My train was part cancelled, and a replacement coachwas provided to where it was now starting from. Unfortunatlythe coach arrived a few minutes after the train departed,so a new train was needed. Fortunatly the TOC's (TrainOperating Company) app allows seat reservations to madeup to 10 minutes from departure and the next train was inhalf an hour - given it's a long journey I was going toget a reservation. Apparently several other people hadthe same idea, resulting in two of us getting a confirmation(both email and in app) for the same seat."Apparently Robert reserved Edinburgh->KingsX and a randomcompetitor reserved Newcastle->KingsX at the same time.It seems that LNER's seat reservation application had afailure of transactional integrity. Hopefully it waseventually consistent.
Best of…: Classic WTF: For Each Parallel
CodeSOD: Looks Guid to Me
Today, we have an interesting one. It's not technically a Code SOD, because it doesn't have any code. It isn't quite a feature, because it doesn't contain a story. It's just some data, from a database table.But it does tell a story.Today's anonymous submitter was browsing through the tables underlying a bit of enterprise software. One of the things which caught our submitter's attention was that the MODULES table had a field MD_ID and a field MD_GUID. Now, it seems odd to have both. Ideally, each GUID is unique. Maybe it was some misguided ideas around how to optimize foreign keys? Maybe it didn't start with GUIDs, and needed to retain the old column for backwards compatibility? There are many, logical reasons why it might be this way.Let's look at the data.MD_IDMD_NAMEMD_GUIDMD_DESC0Defects{e1bb4b51-06e1-454e-8d75-83d6f7a38f42}Defects1Test Plan{fefeb3f5-81fd-472c-af4a-9bbf008f22f8}Test Plan2Test Lab{652b5c42-13e1-40d1-a319-7056c0171006}Test Lab3Requirements{409a58f0-73f6-46b9-a96c-e3851ed09825}Requirements4Dashboard{c67dcd3a-3968-44c9-baf3-a65c81bd329a}Dashboard5Components{df363e91-c0a6-465c-9ef4-820365957c2e}Business Components6ReleasesReleases module has no GUIDManagement7Models{74ce1ffb-6840-49da-b7e3-7e138e1851a1}Business Models8Libraries{e00fdc7f-174a-4b28-aced-f71e02058781}Libraries9Environments{80f6b6d7-c022-4306-9b6f-6a77774d8d5f}EnvironmentsThis is more about the users than the data itself, but I really do enjoy that the description field provides no additional information, and in some cases makes the meaning of the name less clear.But the real special thing is obviously, that the Releases module has no GUID. This also tells us that the GUIDs are stored as strings, which is the wrong way to store a GUID.Is there a good reason why one module doesn't get a GUID? Probably not. But it leaves us puzzling- why not just set one. It doesn't matter! Why is this one special? Why do we break our unique identifiers by not treating them correctly? [Advertisement] ProGet's got you covered with security and access controls on your NuGet feeds. Learn more.
CodeSOD: Certificate of Security
Joe wanted to interact with a social media service's API. As one does, he went out and found a library for his language, and started investigating it. Now, the API was, unsurprisingly, an HTTP based API, wrapped in TLS for security. The library had a handy built-in function which validated the security certificates to ensure they were still valid and hadn't been compromised:
CodeSOD: Black Letters
Johannes started debugging an application, and decided he needed to "share his pain".Here, we're presented with a simple problem: convert a number in the range [0-25] to a letter [A-Z]. Many people would solve this with an array of letters as a lookup table. If they're clever, they'd leverage the character encoding and do some arithmetic.Or, they could just have a gigantic switch:
Error'd: Up In Smoke
Happy Friday to those who celebrate. Enjoy it while it lasts, because Greg L. has some bad news."It was nice hanging out with all of you, but it looks like the Sun is scheduled to expire Sunday morning."It's worse than that: the laws of physics are being replaced.
CodeSOD: A Stack of XML
Alice works with an XML-based RPC system. They send requests, it does a thing, and returns back a response, all surrounded in XML. The service sending the requests, however, doesn't use a well-established parsing library. The result is that, well, the code ends up here.First, though, a bit about the data they expect to parse. It's verbose, but fairly straightforward:
CodeSOD: Don't Read This Email
Evan sent us 545 lines of PHP code from a file called spec_email.php. It appears to participate in sending an email, with a nice big pile of HTML in it. We're going to take it in a few chunks, because... choices were made.It opens with this check, and a few variable declarations:
CodeSOD: Nothing is True
Alexander sends us this snippet, where we change our definition of truth to something which eschews concrete definitions and accepts that existence is ephemeral. Truth and false are just illusions we project onto a reality that is itself just an illusion. In the end, we are all nothing.
CodeSOD: Sdrawkcab Error Handling
When interacting with RESTful web services, there's a depressingly common anti-pattern: always return status 200 OK, but embed a more meaningful status code in the body of the response. Frequently, the embedded status code is just the HTTP status code you should have returned in the first place.This "fixes" situations where you have badly behaving clients that don't do proper error handling, but also breaks the entire point of doing REST.Alice works on an app that, while most of the time the code is decent, has a service that does this. This service also does something even worse: depending on the URL parameters you pass to the query, it may do something like this when it returns errors:
Error'd: Just Beastly
Not to be outdone by Michael R., another prolificparticipant styles himself The Beast In Black.A handful of his experiences follow here. [psst. Mr Black. Check out this explanation of a half-closed interval)Buyer Beast bemoans "I knew that the global situation was bad, but when Amazon starts offering disdiscounts (ordiscountcounts, perhaps?) you know that theworld is truly up the toilet without a paddle roll."
CodeSOD: Extended Models
If I'm being completely honest, I'm mildly anti-ORM. I'm not about to go on a rampage and suggest they should absolutely, never, ever, ever be used, but I think they tend to create a lot of problems. Instead of being a true mapping between our object model and our relational model, they're their own tool, with its own idosynchracies, and a lot of "magic" that conceals its actual operation. For simple applications, they're great, but once you start getting into something more complicated than basic CRUD operations, you're in for a world of hurt. And that's before someone makes a mistake with eager vs. lazy fetching.Today's anonymous submission offers us a good example of another way the mismatch can go wrong between objects and relations.
Coded Smorgasbord: Mostly In One Line
Today's a day for a smorgasbord. We're going to start with a classic kind of bad code, from astephens:
CodeSOD: All the Cases Covered
David's application has loads of unit tests. Many of the unit tests even go so far as to exhaustively test every combination of parameters. So seeing something like this is pretty common:
CodeSOD: Actively Xing Out
Today, I'm honestly not sure that the WTF is in the code we're looking at. Jeff needed to support an older PHP application which used client side JavaScript heavily. This block was copy-pasted many times throughout the code base:
12345678910...