Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-04-28 10:32
Error'd: Supernatural
I read your minds today, and what I saw there said you're all desperate for more Error'd. Lucky you, here's a twofer from LinkedIn!Prospective employeeProgenitus opened an email and reflected "Yes, LinkedIn I am asking that myself. But I hoped you would help me find out about that."
CodeSOD: Default Actions
Bleu supports a Pimcore-based PHP site. Pimcore is a rather sprawling enterprise system for PHP. Like many Model-View-Controller type frameworks, maps HTTP requests to actions on controllers. Bleu's team has several "default" actions configured on their controllers. Let's take a look at a few of them.
A Single Bug
Matt's team had a party after their last release. It was a huge push, with tons of new features, that came at the end of many months of work. On the Monday after the party, they came back into work for unsurprising bad news: nothing is perfect, so there were several issues and defects that needed to be patched, quickly.Since QA is the team responsible for signing off and approving any work, QA is the team that also owns the defect tickets. Matt and his team can't do any work without a ticket, which meant they spent almost an entire day knowing there were bugs to fix, but without any idea of what bugs to fix.The next day, QA finally finished triaging the issues. There were a slew of low priority tickets, none of which were bugs, but enhancement requests- this screen is confusing, this path through the application requires too many button presses, no one can find this option. There was, however, only one bug ticket."Hunh," Matt thought, "that doesn't sound so bad."Upon opening the ticket, Matt discovered that it was indeed bad. There were almost a dozen serious bugs, but for whatever reason, QA had bundled them into a single ticket. This made everybody's life much harder. Every change in the code had to have an associated ticket, every bug ticket had to have an attached test plan, every ticket has to have a single owner and assignee (but Matt's entire team would be splitting this work). Everything about getting this fixed was harder because QA had created a bottleneck by tying together unrelated bugs into a single ticket.So Matt went over to Bruce, the QA manager who'd created the ticket. "Could you please split this ticket?""No, I can't.""Yes, you can. Just abandon this one and make new ones."Bruce shook his head. "You don't understand. These are post release bugs. Which means we released software with bugs in it. Which means the QA process failed. When the management dashboard shows a dozen high priority bugs post-release, management thinks that someone wasn't doing their job properly. That looks bad. So, we make one ticket, roll all the issues under that one, and it looks much better on the dashboard."Matt was offended that anyone would try to game the system like that. QA was making everybody's job harder and trying to conceal issues from management. Well, the joke was on QA- Matt went straight up the tree to the management team.He sent an email, laying out what was happening, and most important, why it was happening. QA was trying to hide the failures in the QA process. Later that day, one of the directors set up a meeting with Matt to discuss the email."So, I understand you have some concerns," the VP said, "and I just wanted to show you how we view that." The VP pulled up the management dashboard, and flipped back to an old release, from a few years ago. Many of the metrics showed red stoplights. "So, here's a release that went badly. Too many tickets for bugs." They flipped to the most recent release. Here, all the lights were green. "And this is a release that went well.""Right," Matt said, "but this release only looks like it went well because they only opened one ticket for many bugs!"The VP nodded without listening. "Right, but this dashboard tracks open tickets. We like releases with only one open ticket. The lights are green, see?""But there are more bugs than there are tickets. They're hiding the fact that there are more bugs!""But this dashboard doesn't track bugs, it tracks tickets."There are few things more immovable than a manager with pretty green lights on a dashboard. Goodhart's Law struck again. Matt admitted defeat and fixed the ticket the hard way. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
Picking Your Consultants
Inilock started making locks back in the 1880s, and has always had a conservative approach to changing things about how locks work. But the world has moved on, and the pin-and-tumbler has given way to RFID card readers and electromagnets.Since Inilock didn't have the internal expertise to build industrial locking systems for commercial customers, they did what any company would do: they hired highly paid consultants. The project started in 2018. These consultants went out and build a lock firmware platform, a server, and a homegrown TCP protocol to handle configuration and setup, handed it in late and over budget, cashed their checks, and vanished, by 2022.The system was not too bad. It was extremely bad. The server used for configuring locks would hang on the regular. That was bad enough, but even worse, the locks would also stop responding. As it turns out, "have you tried turning it on and off again" is not something your customers want to hear when they're locked out of the building. The product was so bad, and had consumed so many resources, that Inilock was facing an existential threat to the company.They hadn't gained any new expertise in software development, so they hired another consulting firm, which is where Christian enters this story. His team was brought in to try and fix this disaster before Inilock locked their own doors for good.The first thing Christian did was track down the source control server and start reading through the code. The server was written in C#, and while the project started in 2018, every choice that was made was frozen someplace circa 2008- using ADO .NET for database access, instead of any of the more modern frameworks that .NET had added.That was annoying, but more telling was the release process. There was no CI/CD. A developer pulled the code, ran "Build..." on their local machine, and then uploaded the binary to an FTP server. Another tool could be run on the target network to grab the binary and distributed it to all the locks on that network.That gave Christian a sense of the overall care that went into the project, but it was when investigating the network protocol and how it was handled that he started to understand why using the software was such a terrible experience.The configuration application wrote records to an MS-SQL database. Another service queried that database periodically. When the data changed, it would broadcast out the new configuration to all the locks via a homegrown TCP protocol. It would read the data from the database, convert it to XML, blast the XML across a TCP socket to each client, and then query the database again, in an endless loop. Well, mostly endless.What the service didn't do was any sort of error handling. Oh, and it didn't insert any breaks in the stream, or give the client any way of knowing how long the stream of data it should be expecting.Every client just had a buffer, scanned the buffer every 50ms, and assumed that everything in the buffer was a single message from the server. This was fine in a laboratory environment where there was very little traffic or latency on the network, but in a real network the clients would frequently check the buffer before the entire message had arrived, or end up with two messages in the buffer. There was no error handling on the clients either, so they'd just hang on the bad data.And since the server wasn't doing any error handling, timeouts or any asynchronous messaging, it'd hang when enough of those connections went down.Ripping out the messaging layer and replacing it with fit-for-purpose 3rd-party library was a great deal of work, but that alone was enough to fix the reliability problems and boost performance of the system by 1000%. The architecture is still a ridiculous disaster, the UI is still a nightmare, there are still all sorts of bad choices, sources of crashes, and the only bits of the code base that have any automated tests are the ones which Christian's team touched. But it's gone from a massive trainwreck of toxic waste to a moderately sized trainwreck of toxic waste.Whether it's enough to save Inilock remains to be seen, but when Christian cashes his checks for being a consultant, he at least knows he made things better. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: Roll On Menu
Mike was refactoring an old web application written in Perl. We joke about Perl being a "write only language," but the original developer wanted to take that unreadable attitude to the JavaScript front-end portion of the application.
Error'd: [ insert title here ]
This week we received a plethora of failed text substitutions. I'd like to find a pithyname for this sort of error; suggestions in the comments here will be welcomed.But before we dive into those typical errors, repeat contributor Valts S. has shared a classic blunder:"White text on white background. Who among us hasn't done this in our lives? :)"
Succesful Deployment
Typos are the bane of delevopers' existence. For most of our typos, the result is a syntax error. It's quick and easy to find and fix. But any time we're working with strings (or in languages where variables are declared at use) there can be many more subtle bugs.So when Abigail's company sent an intern off to fix a few typos, they thought this was a lovely little low-hanging fruit bug to fix.There were three typos which needed to be fixed.
CodeSOD: This Equals Success
There are common errors that are (or were) once so common that we've built tools to help us avoid them. So I was a little surprised to see this JavaScript from Annie's co-worker.
CodeSOD: Loop the Loop the Loop
David's organization didn't fully understand why you bring interns into a company. The purpose of an internship is to provide an educational opportunity and resume line-item to someone looking to enter the industry, and possibly recruit said intern after they graduate, getting a new-hire that is more ready for your team than average. It's good for the intern, it's good for the overall health of the industry, it's good for the company building its network of professional relationships and recruiting opportunities.The purpose of an internship is not to just throw tickets at an intern, and let them commit code to your main branch, unsupervised. Unfortunately for David, and for the poor interns that preceded him, that is what the company had done.
Representative Line: Path To
Sometimes, you see a code sample and you almost scroll by. "This isn't bad, I see it all the time." So it took a second glance to see the awful charm of what Henrik H found.Henrik was asked to join a project to fix a high load website having "some issues". Here's a JavaScript tag that was included on nearly every page.
Error'd: Number Theories
From our readers this week, we have a couple of mixed numbers. David B even gets a twofer.Trainspotter Daniel notes "The LIRR now has the technology to pass 9 minutes with only 5 minutes of waiting!"They're apparently doing something nonobvious aboutscheduled versus expected times in one context, but notin another. Maybe the readers can figure it out.
CodeSOD: Select Start
"John Doe" was asked to take a look at a slow-running application. It didn't take too long to discover that the application was slow because the database was slow, but figuring out why the database was slow involved digging deeply through some logs.The database was a central system, which many applications connected to. Every ten minutes, performance dropped significantly, and it just so happened that every ten minutes a batch update process ran.
CodeSOD: Rounding Currency
Moz works for a company that needs to handle financial transactions. They use Delphi, which has a handy-dandy fixed precision Currency type, which should make this easy.Of course, someone opted to do most of the math in double precision floating points anyway. Which lead to this function:
CodeSOD: ThreadSafeArray
As frequently stated, concurrency is hard. Ensuring that all of your data is accessed in a threadsafe manner is a real challenge. So when Ryan saw a method called ThreadSafeArray, it seemed like an obvious utility method: wrap an array up in a thread safe accessor, right?Well, the signature of the function made Ryan suspicious. And the code...
CodeSOD: All the Time in the World
Time zones are hard. And, to my surprise, if you want to enumerate all the time zones in the world in C#, there isn't an easy way to do that. You can enumerate all the time zones configured on the host computer (in Windows), but that may be incomplete and also may use idiosyncratic names, since it doesn't use the IANA database of timezones.This leaves developers with a three real options. The first would be to either load the IANA database yourself, and the second would be to use a library that provides it.Which, Louis's team did the first- they maintained a time zone database in their application database that contained all the time zones, in their canonical names.Or, I should say, most of Louis's team did the first. One developer found the third option. They didn't use the database. They didn't use a library. They just hard-coded all the options into the UI:
Error'd: Soups On
Joseph H. is a little salty about vapid adverts. "Vacation planners long ago figured out that the GreatSalt Lake didn't make for great resorts.They must be referring to the up-and-coming land cruisesacross the desert plains of Utah. Definitely that. Noother possible explanation."
CodeSOD: Threading in JavaScript
The easiest way to write programs that support concurrency is to not. JavaScript in the browser is famously single-threaded, unless you add web-workers, which have a very specific way of interacting with your main script that avoids most of the pitfalls of concurrency. Or at least makes them easy to avoid.But what if you had a developer who didn't know any of this, and just assumed JavaScript was multithreaded and needed locks, but didn't understand how locks worked? Then you'd get something like this code, from an anonymous submitter.
CodeSOD: The Administrator Hack
A decade ago, Adam was doing support on a classic ASP application. This was an internal application which tracked sales accounts, employee reviews, and general HR information. Now, the company had a real HR system, but some of their internal processes predated the HR system, thus they had a custom application that did things the HR system already did, but they already owned the application and didn't want to retrain people.One day, a manager logged in, started doing some work, took a break, and came back, only to discover that when she pulled up a list of employees, she no longer saw her direct reports, but instead saw all of the employees at the company. She reported the bug and Adam picked up the ticket.Adam's first suspicion was that her session timed out, and then there must be something wrong in how the session got initialized.
CodeSOD: Really Fast Code
Tracking the performance of an application matters. Too often, developers will try and tune and optimize an application based on their instincts about where the performance is bad- instincts which are frequently wrong.Remy L's company included performance tracking blocks in their code, enabled by a debug flag. According to the performance stats, their program performed incredibly well. There were rarely ever any long-running methods.Unfortunately, these wonderful statistics didn't jive with the experience of the users, who would often wait thirty seconds to a minute for the application to respond after clicking a button.And also, as one weird thing, the performance monitor sometimes reported that methods took negative amounts of time to execute, making this program fast enough to break the laws of time and space.Why was there such a difference?
CodeSOD: Classic WTF: The Single Sign On
Error'd: Redmond Calling to the Faraway Towns
We had to stretch just a little bit to make a purelyMicrosoft-themed column this week. Gone are the days when it was trivial to make BSOD jokes and rail at OutlookExpress. But they still give us material for some lolz now and then.Well-rested reader Michael W.remarks "After waking up my laptop from a long period of slumberand logging in I am greeted by the attached error messageon my desktop: You'll need the Internet for this.Which makes me wonder what do I need the internet for?The dialog has no title and it's not clear if it's connectedto any other open windows. Whatever the ''this'' is supposedto reference to stays shredded in mystery providing no contextwhatsoever. But I guess it's at least a step up from those''Internal Error'' message dialogues.And yes, of course a solution can be googled for, but alas mostof those pages will tell you how to fix a network connectionproblem but also mostly won't tell you to what applicationor use this dialogue relates to (apparently it's Windows 365 subscription related)"
CodeSOD: I Feel Asleep
When your program needs to pause, there are several options. The first is a pure busy loop- usually a bad idea, but frequently more efficient for very short delays than other options. The "standard" is to sleep your program- just tell the OS scheduler to let other programs run and to wake you up after some interval. In multithreaded programs, you'll frequently sleep one thread while waiting on others.Which is what Cisco's co-worker sort of did. Sort of.
CodeSOD: Serialization and Deserialization
Over 15 years, an intranet application with a small userbase has gradually become "mission critical". The original developers and all of the maintainers have been folks who didn't have any software development experience, beyond "I took a bootcamp once ten years ago" and "I can do Excel macros". At least they didn't 15 years ago, but over the past 15 years, it's turned into some people's full time job.Krister E. was hired to try and turn this into a mature software product that didn't require constant babysitting and tending to keep it from crashing, burning, exploding, and leaving a cloud of fallout behind it. There were some challenges to that.
The Debugging Tool
When Allan C's company, Initrode, got acquired by Initech a few years ago, it sounded like actually good news for the rank and file employees. Initech had a product in the same line of business as Allan's employer, and it was better in most ways, at least according to customer feedback. Allan's team had built some features into their product that Initech wanted, and Initech was also looking to grow rapidly, so there was no fear of layoffs. In fact everybody got a mild raise, and only a few middle managers were asked to leave the company.That's about where the good news ended.Initech built their product in JavaScript, but they had frozen their codebase on a version of the JavaScript runtime from the early 2000s. For Allan, who had been doing modern JavaScript for pretty much his entire career, this was like going back to stone tools. The code had few attempts at modularization- some of the code had the courtesy to create its local variables in an immediately invoked function expression, which was how one did modules before modules existed, but most of the code just slapped variables and functions into the global namespace and hoped for the best.That made the code difficult to debug, as there were loads of unintended side effects- side effects that frequently resulted in exceptions. Fortunately, all the exceptions were caught... somewhere. Frequently they were caught, handled, then a new exception was thrown with a different error message.Now, that might sound like it makes it difficult to understand the causes of exceptions, as if you're throwing entirely new exceptions, you're destroying the stack trace information. But you have to remember this was a JavaScript was an antique: exceptions didn't have stack trace information.Also making things difficult to debug: there wasn't a debugger. Your solution to tracing through the code was putting a lot of print statements into it, and trying to understand the output.One day, while bashing his head up against a particularly thorny bug and wishing for some sort of useful stack trace information, Allan had an idea. Since all the important functions were already in the global namespace, it wouldn't be hard to write some JavaScript that wrapped every function with some debugging and tracking behavior. Since the runtime didn't provide a stack trace, he could wrap every function and build a stack trace as they were invoked. And when an error happened, he could log it at the level where it happened, and not need to put print statements everywhere.As solutions go, it was cumbersome and hacky, but it was better than anything else Allan had available to him. The thorny bug that Allan was fighting with became trivial to fix once he could see the stack trace and the source of the errors.In coffee-maker and water-cooler conversations, Allan hinted at his great new tool, but no one else expressed any interest in what he was working on. So, he plotted out a demo. He created a simulated use case- he inserted a bug into a module that he thought would be difficult to find. He ran the code, and got an error message: "Found an error in the column module foo"."Great," Allan said. "So how would we track this error down?" Allan was feeling pretty clever at this moment, as there were dozens of "column module" types, so tracking down the actual source would be rather difficult.Gary, the original architect of the code base and resident curmudgeon said, "Just search through the code base for the error message."Allan felt stupid- he hadn't planned for that specific solution. He hadn't considered that the error message might be unique enough to find a specific file. Unfortunately, the first result was the file he'd modified. "Uh, yeah, let's... um... check that."Allan added a print statement to the file. If Gary had found the bug, it would print a "Found it!" message, and no one would ever want to use Allan's tool. Allan re-ran the program. The "Found it!" message didn't appear.Everyone was shocked, especially Allan. Gary was wrong? But so was Allan? There was only one way to figure out what was really going on: use Allan's debugging tool. He loaded up the tool, re-ran the program, and within seconds was able to pinpoint exactly what was going on.While their search had turned up the first instance of "Found an error in the column module foo", there were several more. As it turned out, the place where Allan had inserted the bug was actually in "Column Module Bar"- which itself was just a copy/paste of "Foo", with minor modifications.Allan was overjoyed. For a moment, his demo teetered on the edge of catastrophe, and then his own errors highlighted how easy it was to make mistakes in this codebase, and how quickly his tool could help diagnose them. He highlighted the line containing the bug, and waited for the accolades from the team for being so very, incredibly clever."Maybe," Gary said, "instead of wasting time with your tool, we should just fix the error message." He typed for a few moments, and then said, "There. Pushed a fix. Can we get back to work now, or do you have more ways to waste our time?"It was at that moment Allan realized the code wasn't accidentally terrible, it was intentionally terrible. It was the way it was because Gary wanted it that way, and Gary wasn't going to let it be any better than it was, no matter what Allan did.Allan was the first of the Initrode team to abandon ship, but he wasn't the last. And once the first wave of experienced, senior talent started jumping ship, things quickly got worse for everyone remaining, and they jumped ship too. Within a year, everyone was gone except for Gary and a pile of junior developers too inexperienced to know how bad their working environment was.Allan's debugging tool is likely still somewhere in their source control repository, collecting digital dust, and waiting for one of those junior developers to discover it. [Advertisement] ProGet's got you covered with security and access controls on your NuGet feeds. Learn more.
CodeSOD: Negative Creep
Candice has inherited some legacy C++ code. It's legacy enough, for example, that there are about 15 definitions of a boolean, depending which headers you include. It contains, in Candice's words, "an ambitious attempt to #undef return".In short, there are plenty of horrors in the code. But this particular short snippet is the one that drew Candice's attention.
Error'd: The Chemistry Is Gone
Sometimes the spark just isn't there.For instance, Eric R. is just not that into Chemical Engineering."Looks like I'll still be missing your articles, then, huh?"
CodeSOD: Page Up? Page Down. Thumbs Down.
Putting a full-featured IDE on every user's desktop and providing them basically no guidance on how to use it would, in most circles, be considered a mistake. That mistake is also known as "Microsoft Office", which continues to haunt us.Now, much of the macro-based application development in Office applications is written by non-programmers. But there's still a disturbing amount of code written by people who should know better, and thus you end up with mission-critical applications written in Microsoft Access.Douglas inherited one such database. At some point, one of their end users got confused- this user was used to mainframe-based applications which present screenfuls of data and don't have scrolling. So, when presented with a window that could scroll, they were flummoxed. Why did the data they were looking at go away? Disabling scrollbars only got them so far, as the page-up/page-down keys still worked, so the obvious fix was to disable those keystrokes as well.
CodeSOD: Functionally Null
Starting in Java 8, Java introduced support for lambdas. Under the hood, they're a soup of anonymous classes, generics (and the associated type erasure), but they at least look like (and mostly behave like) lambdas. Functional programming came to Java a decade ago.Ich's predecessor saw this new tool and decided that they needed to use it everywhere.
CodeSOD: Simple Form Validation
"This is so easy, how could someone screw it up?" is a wonderful case of ambiguity in English. Because the question means two things, potentially. The first question is "how (is it possible) that someone could screw it up?" This question is is built upon the assumption that there are limits to how dense people can be, which is a faulty assumption: there are no limits.The other interpretation is "in what way can someone screw it up?" This is a far more interesting question, as human error is and endless array of fractal snowflakes, no two exactly alike.For example, Nathan had a co-worker who needed to take data from a text box on a form, and convert it into a numeric type. "Parsing form input" is such a common task, you have to wonder how does someone screw this up:
CodeSOD: More and More Replacements
You can do a lot in an SQL query. But sometimes, you should probably do less, like this ad-hoc ORDER BY clause from KT.
Error'd: Short Films
Frequent flierCarlosquickly quipped"I'm waiting for my plane to take off from Washington-Dullesto Chicago-Midway. Just enough time to watch Innerspace."
CodeSOD: John Told Us
Comments are an important part of making code comprehensible to other people, especially when they explain the why- linking lines of code to requirements, specification documents, etc. Karl used to work for a large company that maybe didn't see comments that way.So, for example, when you see a line of code like this:
CodeSOD: Random Comparison
Justin's co-worker needed to validate a UUID/GUID in C#. So they wrote this:
CodeSOD: Randomly Switching Images
Ronald writes:
CodeSOD: Array Length Validation
Mike sends us some VB.Net code today.
Error'd: All Wet
TodayJP wrote in to proudly unsmirch the Finnish reputation."Some time ago, you blamed the Finns for strange patterns on Valts's weather map.I am delighted to report that the *real* culprit isrevealed when carefully examining the Finnish MeteorologicalInstitute's weather map of the whole of Europe." I stand corrected, JP.
CodeSOD: A Piece of Switch
Functional programming is fine. It's a different way of thinking about programs, but it makes some problems very easy to describe. It's a tool that belongs in the toolbox, and you should use the right tool for the job.LH's co-worker doesn't quite take that approach. Their solution to pretty much every problem is to use lambdas, and the functional switch expression in C#. But, when combined with their coding style, it creates some... interesting code.
CodeSOD: A Case of Conversion
Mattijs's co-worker was responsible for an HTML-to-PDF converter that was used internally. While TRWTF is always going to be PDFs, there were some odd choices used in the converter, starting with the function named ConvertTagsToLowerCase.
CodeSOD: Universal Catch
A common pattern is "global error handlers"- functions you call in your catch block that do some task, usually logging, when an exception occurs. Given that exception handling frequently involves a fair bit of repeated code, centralizing that isn't a terrible idea. So when Magnus found code like this in the codebase, he didn't think much of it:
CodeSOD: Load, Load, Load your Deps
It's not uncommon for web applications to fetch key dependencies from remote, public CDNs. Why host Angular or jQuery yourself, when Google will do it for you? That, at least, was part of the logic underpinning this old code Dan found.
Error'd: Oldies are Goodies
Sharp-eyedJeremy P.goes a little meta, and we like little em meta."Seen on a well known web site that publishes technology snafus.
CodeSOD: Error While you Wait
Structured exception handling is a powerful way to describe how your program reacts to error conditions. But it's not available in a language like C, and thus C programmers have come up with a variety of ways to propogate errors. Frequently, functions simply return error codes. Some error handling practices use the dreaded goto to jump to the error handler.Or, they do what "Maple Syrup"'s predecessor did for all of their error handling code:
CodeSOD: All Thumbs
Nick L supports a hardware system that should autodetect a USB drive when inserted, and then load a config file off of it. This fairly simple task is made more complicated by the freelancer they hired to solve the problem, who has some... interesting approaches to writing Python.
CodeSOD: Taking up Spaces
Anderson sends us a bit of C# code that does the simple job of removing multiple spaces, i.e. it converts "AB" to "AB". And, much to my surprise, I learned something about C# from reading this code.
CodeSOD: Just a Copy of Copy
I don't think anyone would argue that BASH provides a good scripting environment. It provides a commonly available scripting environment that even its successor shells attempt to emulate. But it's idiosyncratic, at best, and leads to bug-prone scripts.But there are certain tasks that it excels at- specifically, the kinds of tasks that you'd normally do from the shell but just want to wrap some light automation around. Want to scan a directory and then copy some subset of the files out based on user arguments? BASH is your friend! It's just some basic conditionals and some cp commands, what could be easier?Well, I'm not sure, but Radu's predecessors found a way to make it harder. Because they didn't use the cp command anywhere. ANd why should they? I mean, look at the flags documented on the man page: cp [-R [-H | -L | -P]] [-fi | -n] [-alpSsvXx]? Who wants to learn all of that? They certainly didn't.Whenever they needed to copy files in a script, they did this instead:
Error'd: Total Zeroes
Today, scattered amidst the gems, you will find a wholebunch of zeroes. No, not the contributors!The zeroeth submission of the day is from Bluejay A. who sagely notes "That shouldn't be too hard to find."
CodeSOD: Fast Conversion
Clara had a database of users. The EmailAddress field in the user table was, by design, nullable, but some downstream applications didn't like nulls and wanted something there. Now, it didn't particularly matter what the values were, just that there were some, so Clara wrote up a quick stored procedure that would return the users with the null emails converted to the format BlankEmail_YYYYMMDD, e.g., BlankEmail_20230726.This was all well and good until one of the senior developers decided that Clara's use of the T-SQL date functions was killing performance. They made this decision based on being the senior developer, but not based on any metrics or performance monitoring. Real seniors don't need such trivialities- they know what badly performing code is just by looking at it.So that senior developer wrote this function, guaranteed to perform better.
CodeSOD: Base of the Hash
Jamie Kitson followed the instructions to integrate their software with a new payment provider. The payment API was fairly straight forward, mostly a straightforward call to a web endpoint. As an error check, the request required an base-64 encoded, MD5 hash of its contents appended to the end of it.Jamie did just that, in C#. And the payment processor balked: the hash was wrong. There was no information beyond that, just "bad hash".Jamie checked the output, hashed many different possible values, confirmed that a different MD5 hashing library generated the same results, and did all of the sane things one might to do check and see if you were correctly hashing an input. They checked the documentation, confirmed that they were hashing the right contents, confirmed that there wasn't any salting, confirmed that nothing they were doing on their end was wrong.Eventually, Jamie tried the JavaScript sample code provided by the vendor. And it gave a different result.
CodeSOD: The Set Up
My heretical opinion on object-oriented programming is that I don't like getters and setters. They're often trivial boilerplate (boilerplate is a code smell), or they're hiding behavior where behavior probably doesn't belong.Yes, yes, I understand the importance of encapsulation, but in a lot of ways, trivial getters/setters break encapsulation. void setFoo(T foo) { this.foo = foo; } does nothing to protect foo against unauthorized modifications.So while I understand encapsulation, I don't think I understand it as well as the Senior Engineer responsible for today's anonymous submission. Because they certainly fixed the encapsulation issues with setters:
CodeSOD: The Apex of Development
David S writes: "I'm undertaking a refactor and facelift of an Oracle APEX application."That, already, is the real WTF. Oracle Application Express, or APEX (formerly ApEx, formerly HTML DB) is Oracle's offering in the low-code business application space. Using a WYSISYG designer, you build pages and bind them to SQL queries, stored procedures, etc., allowing users with little to no programming experience to design data driven applications.Like all such tools: it works fine for the very simple tasks, but once you try and model real-world applications in it, everything falls apart. Some of this is just the nature of low-code tools. Some of this is because much of Oracle APEX is implemented in Oracle's PL/SQL database language. Some of this is because Oracle keeps bolting features onto it, hoping that it finally gets the traction they want for it.Which, on the scope of traction, you can see the collection of applications folks want to admit to having built in APEX here, which includes "Target Executive Search" (a job site for finding executives) and "My Karaoke". APEX has range. There are dozens of other such sites, including Built with Apex itself..But none of that is David's problem. David inherited this PL/SQL code which is invoked from an APEX page.
12345678910...