Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-11-21 20:01
CodeSOD: Wear a Wrap
While jQuery isn't as popular today as it once was, its still a widely used "utility belt" library. Its popularity arises from the fact that it takes cumbersome APIs and wraps convenience functions around them.But what if those convenience functions are too convenient, like Ryan's co-worker found. For example, if you want to perform an asynchronous HTTP request using jQuery, you could do something like:
CodeSOD: Hey, Backoff!
The Strategy Pattern, like any other design pattern, is supposed to help us write code that's flexible and easy to modify. In the case of the strategy pattern, you have one class, the Context, which has a member which implements a Strategy interface. The actual implementation lives in the Strategy, but the Context is the object that other code in the program consumes. Ideally, this means that you can change the behavior of your Context by simply swapping a different Strategy implementation in.On the flip side, when it gets out of hand, you might end up like Dotan, consuming an API from a major cloud vendor, written with a terminal case of "Pattern Brain".
CodeSOD: Administrative Transfer
When the pandemic started, a lot of companies needed to cut back, and Initech was no exception. In the Before Times™, Initech had an offshore development team that maintained an application inherited from an acquisition. Now that everyone was tightening their belts, though, that had to go. The offshore team was released and the application they supported ended up in the hands of Lovelace.Lovelace dug in, and they quickly discovered a few things. From 2010-2017, the application's idea of source control was a folder on an FTP server and a lot of files named some_module.php.old and some_module.php.donotuse. In 2017, someone put the project into Git, but the commits were just point-in-time snapshots of the FTP folder. Deployment? Just work right on that FTP folder, it's fine. And if you forget to commit those changes back to source control? No biggie- consider the FTP folder the source of truth.Then again, when Lovelace saw the "truth" that was there, they weren't exactly excited to be supporting this PHP application.
Error'd: The Hardest Problem
It has been infamously stated that the two hardest problemsin computer science are naming, caching, and off-by-one errors. Mixing and matching arrays indexed from 0 with arrays indexedfrom 1 could be a special-case of the off-by-one error.The zeroth of a sudden rash of anonymous posters spotted this initial example, coughing "Pre-increment seems somehowinappropriate here."
CodeSOD: A Cup of CIDR
Marco sends us some code that he wrote, back in the far off days of 2003. He wrote some code to handle network addresses. Unfortunately, it never quite worked. Specifically it could only handle addresses in the /24 subnet.Now, this was written in Perl, so you know it involves regexes.
CodeSOD: A Forgotten Memory
Starting in 1985, a tiny little language called Clipper briefly conquered the world. It was a dBase-derivative, with the bonus that its programs could be compiled and run as stand-alone software on MS-DOS. That meant small programs which couldn't justify getting time on a mainframe or a minicomputer could be whipped up to run on a desktop. It was popular, and for about a decade, it was everywhere. Then Windows 95 came out, and Clipper refused to pivot to Windows and became a footnote in history.It mostly worked pretty great, or at least as great as one of those tiny business-focused languages ever got. Unfortunately for Drake, he encountered some issues in the latter days of Clipper in the early 90s.Drake's team wrote an image display library for Clipper programs. An end-user of their library complained that it crashed when displaying images. They supplied a sample program that replicated the issue, and Drake and his colleagues were able to repeat the issue.The core pattern was: allocate memory for an image, display the image, release the memory. Repeat that a few times, and eventually it crashed. There were a few other memory allocations along the way, and they all went through Clipper's memory manager.So Drake and his team started stripping back their code, commenting out operations until they had a bare minimum program which could replicate the crash. By the time they were finished, the only code left was the code which allocated memory and released it. The simple test case program simply performed a series of memory allocations and releases, and repeated that, printing out the iteration number.On some machines, the program crashed after 22 iterations. On others, it crashed after 151. It was consistent, always crashing on the same iteration on the same machine. Machines with otherwise identical hardware could end up being in either the 22 or the 151 group. A consistent program to reproduce the bug meant that Drake had something to send Nantucket, the company making Clipper.Drake explains what happens next:
CodeSOD: It's Not None of Your Business is True
Patricia's employer hired her because she knew Python. They were a Python shop, at least at this point, but they'd never actually hired a developer with Python experience before.At some point, their PHP developer wanted to branch out, and decided to solve a problem using a small Python script. It was very successful, and features got added to it. In a surprisingly short amount of time, the script expanded until it was two separate web applications which were absolutely critical to business operations.It was a bit of a mess, when Patricia took over. The code was split across three source control repositories. One was for "Application A", in its entirety. One was called "Application B Backend", which as the name implied was the backend of Application B. The third was called "Application B" and was described as the "front end" but it was actually a copy of "Application B Backend".It was 40,000 lines of copy-pasted nonsense, and the core of it was a module called "gsf" or "general standard functions". It was almost all of the shared logic across modules. It was designed so that it never raised an exception, and instead every method that could possibly have to deal with an exception condition instead returned a tuple: (actualReturnValue,successBoolean). Thus, you could invoke something like this:
CodeSOD: Switch Kicker
As covered previously, game code generally doesn't represent an interesting WTF. But bad e-commerce code certainly does. So today, Rhys sends us some JavaScript from a web-based fantasy-football (for non-USA values of football) site. Given that it handles microtransactions and in-game items passed between players, it's definitely more on the e-commerce side of things than anything else.And much like that previous article, this one does involve a very large switch, but before we get to the switch, we have to get to the state validator:
Error'd: Down the Rarebit Hole
This week's Error'd episode includes a bonus submissionfrom our good friend A. Bargle, at no extra charge. TRWTF is inthe browser, perhaps, but it's just so gosh darn funny.It's likely that what tickles me is entirely inscrutableto all of you(especially those coming to English as a second language),and if so, I apologize.But at least one of us is having a good time!Not actually a hydrologistCarl C. has uncovered evidence of an entirecadre of wayward rivers roamin' the wikipedian underground."I got so excited by this that I forgot why I was lookingup the Nueces River on Wikipedia." It's not justthe poor lost Rubicon!
Double Bagged
Many years ago, Yazeran needed to work with some floor-plan data. Now, fortunately for Yazeran, a vendor had already collected this information and packed it up behind a SOAP-based web service, so it would in theory be easy to get. This was long enough ago that SOAP was all the rage, and computers with multiple gigabytes of RAM were still on the higher end of things.In fact, there was an end-point called GetFullDataExtract which promised to, as the name implies, get him all the data. Yazeran didn't need all the data, but the other end-point, GetGMLBuildings returned only the subset of data Yazeran didn't need. So Yazeran simply had to request too much.Yazeran fired up a wget session with all the appropriate credentials and waited. And waited. And waited…When the 20MB XML response finally downloaded, minutes later, it looked like this:
CodeSOD: A Commentary on Military Force
Once upon a time, Simon worked for a company making software for missile systems. This was serious work, with serious testing procedures, and important standards around documentation.Shortly before a live-fire test of a missile system, Simon knew better than to make any code changes, but he did want to improve the documentation. Adding comments was pretty low risk, so he went ahead and did that. By the time he was done, the Turbo Pascal code that controlled the missile looked like this:
CodeSOD: Put Down the Pipe
Camden's team works on an internal Angular application. Angular is constantly releasing new versions, and while they're largely backwards compatible, as the rule goes: every change breaks someone's workflow. Camden's team started to upgrade to Angular 12, only to discover that one of their dependencies wouldn't resolve. It refused to work with any version of Angular greater than 8.The specific dependency promised to safely sanitize external resources, like DOM snippets and URLs fetched from an external source. At its core, it wrapped around the Angular DomSanitizer object, which provided all the plumbing for handling sanitization.So the TypeScript method looked like this:
Error'd: In the fullness of time.
RegulargleArgle garbles"It's an advertisement. At least... it says so." Hey, if you can'tbelieve advertisements, what can you believe?
CodeSOD: Promotional Development
Upgrading to a new point release on the Linux kernel isn't the riskiest thing you can do in your infrastructure, but it's not completely without risk. It's not so much that the kernel maintainers are playing fast and loose- they're a very conservative bunch for the most part- but some application code might be making assumptions that become incorrect in the next release.For Ramona's company, that happened. They updated the kernel, and immediately one of their libraries, written in C++, started segfaulting. Now, the developer behind it was still with the organization, but had climbed the ranks- he was no longer a Software Engineer, or even a Senior Software Engineer, but was now a Senior Solutions Architect and was not to be bothered with trivial things.So without bothering the very important architect, Ramona had to pick apart the offending C++ code on her own. It was older C++, and that was always worrying- conventions and style had changed a lot since this was written. There were no signs of any documentation or tests or anything that would help someone understand what the code was doing.Fortunately, it turned out that the code was simple. Well, "simple". It was a pile of system calls. No, not syscalls, but calls to the system function, which allowed the C++ code to execute shell commands. Essentially it was a giant shell script wrapped in C++ code, and the C++ code didn't contain any logic to handle error, exceptions, or even verify that the return buffers contained valid data.So, it was dangerous, pointless C++ code, but surely the Senior Solutions Architect had a good reason for writing it in the first place? He'd never have risen to such stratospheric heights in the company without having a good reason for doing that?Ramona took the risk and contacted him: "I'm a little unclear what this code is for? Why is this in C++?""Ah," the Architect replied, "I was learning C++ at the time, and everything looked like a C++ solution. Plus any chance to improve my skills!"The fix was to junk the C++ and replace it with a shell script. But it did mean that Ramona started to pay attention to what the Architect was doing, especially when the Architect got yet another promotion to "Software Manager". This allowed him to use his experience and advanced decision-making skills to really make mistakes.For example, they had a bunch of older rackmount servers, about $100k worth, and a relative handful of new servers. Now, the new servers could provide all the capacity they needed right now, and as they grew, they'd want to replace the old servers with even newer ones- so he might as well chuck all the old servers now and make room against that future day.There was just one problem. The Architect-turned-Manager had also decided that the development team was suffering with laptops that were, on average, two years old. They all needed new computers, in his opinion, so he'd already spent the capital budget on that.This meant that, when they needed to expand their server capacity, there was no money to do it, and no older hardware they could press into service as a stop-gap. This made end users angry, as everything became less responsive or outright failed. That made management angry, because angry users hurt the bottom line, especially when it meant they were violating SLAs.The good news is that the company has an opening for a new CTO. The Architect-turned-Manager is already angling for that promotion, and odds are good that he'll get it. Ramona, on the other hand, is already polishing her resume for a change to another job entirely. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Getting Reported
Monica sends us a code snippet that comes from her organization's home-brewed reporting engine. She writes:
The Biased Bug
Back in the 90s, Steve was the head (i.e. only) programmer and CEO of a small company. His pride and joy was a software package employed by many large businesses. One day, a client of Steve's named Winston called him concerning a critical, show-stopping bug. CEO Head Programmer Steve was also the Technical Support Lead, and thus he faithfully took up the issue. Over the phone, Winston carefully described the steps needed to reproduce the crash, and Steve walked through them. At a certain point, entering data and hitting Return rendered the program unusable for Winston—but not so for Steve. Much back-and-forth ensued as Steve tried to figure out what Winston was doing differently, and the frustration in Winston's voice mounted every time he had to reboot the system. It was as if the program had something against the poor man.Since they weren't getting anywhere over the phone, Steve decided he had no choice but to drive out to Winston's office to continue troubleshooting in person. They made arrangements to meet up the next morning.Once they got together, Winston was easily able to demonstrate the problem. Then Steve sat down at the very same computer, typed exactly the same things ... and everything was fine. They tried again several times, and it really seemed as if the program could sense who was sitting before it. Poor Winston could never catch a break.Just as Steve despaired of ever figuring out the issue, he happened to get a good look at Winston's hands as he typed."Hang on!" Steve cried as the solution hit him. "I see the problem here. The parser is expecting a double quote there. You're typing in two single quotes."Winston glanced to him with confusion. "Well, how else do you make a double quote?"Steve was dumbfounded at first. Nevertheless, he patiently walked Winston through the difference between typing two single quotes and one double quote using the Shift key."Huh!" Winston said. "The typewriter I learned to type on didn't have anything like that."Steve frowned. "It didn't have double quotes?""There was no key for that. You had to type two single quotes," Winston replied with an authoritative nod.That must've been quite the old typewriter, Steve thought. He'd had experience with typewriting in his own youth, and remembered Shift keys and double quotes on the models he'd used. It was true, though, that the earliest typewriters only typed capital letters, and thus had no Shift keys. When writing documentation, Steve had never imagined needing to explain something so regularly taken for granted among computer users. Thankfully, Winston was quite pleased with the lesson. As Steve drove home, he knew he still had to come up with a means of handling bad input in a more elegant fashion, but at least he knew his program wasn't malevolently sentient, just picky. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
CodeSOD: Inner Exceptions
One of Raquel's junior developers was having some troubles. They had a Lua script that needed to call out to a Redis store to fetch data. The poor developer was getting useless "failed to communicate to redis," message and needed help figuring out what was going on.Of course, the Lua script wasn't the problem. The company was building a full on Inner-Platform. The core application stack was actually in Java, but it was extensible with Lua scripts. The Java code was meant to handle all the plumbing and interacting with the data store, and the Lua code could then just be where developers put their business logic.The Lua code was fairly straightforward, at least at a glance:
Error'd: Guantanamera
GringoTimothy W. shivers"It's going to be a cold time in Havana tonight!"
CodeSOD: Leaky Logs
For years, Carla's company had a Java application with a memory leak. No one had the time, energy, or budget to actually do anything about the leak, so they "fixed" it by just forcing a nightly reboot.When Carla asked about the nightly reboot, the elders who had been around for awhile simply said, "there were some issues we couldn't track down."Carla was assigned a task to go track down some of those untrackable issues. The first thing she discovered was that when she changed the logging level from its production settings to "DEBUG" mode, the application crashed in minutes instead of days. That piece of information sent Carla looking at the logging code to see what was happening.
CodeSOD: A Little Obtuse
AngularJS, (not to be confused with Angular, its successor project and ostensible replacement) made some… interesting design choices. Controllers existed in a tree, mapped to the DOM, and were glued together by a special object called $scope. You would store your data in the $scope, and depending on exactly how you did it, that data could be accessible at various levels within the tree. $scope also doubled as an event bus, so controllers could send messages up and down the tree as needed.In short, there's a reason why AngularJS fell out of favor.Still, during the era when AngularJS was the new trend, David's co-workers wanted to switch to using AngularJS. Unfortunately, they didn't know AngularJS, and only knew jQuery, so this snippet demonstrates their approach to building AngularJS applications:
Multilingual Development
Lisa's company needed to add some custom functionality to a third-party application- IniERP- which was made easier by the fact that the company had a SOAP web service to interact with. The vendor supplied Java sample code for building the service, so it was trivial for Lisa to build her own code to automate those interactions. And everything went fine, and her users were happy.So fine, and so happy, that other teams heard: "there's a way to integrate your applications into IniERP." Every department in the company had business processes which touched IniERP on some level, so "Lisa built a thing which lets you do this!" got her a lot of emails.There were issues: there was only one "service" account configured by the operations team, so anyone wanting to interact with the service needed to share an account. For that reason, Lisa resisted sharing her solution until ops made a better way to provision accounts, but demand was so high that management pressured her into sharing her code, the documentation, and the credentials.And despite the obvious problems, even that went fine. Mostly. Because most of the teams either had the IT staff available to do the work, or realized this was beyond their technical skills and gave up. Then there was Bert.Bert was a developer on one of the web teams and wanted to integrate their applications into IniERP. So Bert fired up his IDE, hit copy-and-paste, and went to town. Accessing the HelloWorldWS testing service went great, and with that confidence Bert went straight on to accessing the real web service- and that didn't work.Bert sent Lisa an angry email, complaining that her samples didn't work, that obviously she didn't know what she was talking about, that he'd wasted three days fighting with her bad code, and that she shouldn't run around telling the company that she was so smart if she wasn't able to release code which worked. "You shouldn't release what is essentially pseudocode and then tell people you've fixed their problems!"Politely, Lisa offered to take a look at Bert's code, and see if she could spot the issue. Bert resisted, at first, but eventually relented with the comment: "It's the code you supplied, so if it's wrong, that's on you."There were a few obvious problems in Bert's code. The first, and smallest one, was that in a few spots instead of copying a constant declaration and its value, he just created a constant and set its value to its name. That was weird, and certainly enough to explain why his code wasn't working, but it actually wasn't the reason why it wasn't working.You see, Bert was a PHP developer. He was building a PHP application. But he copy/pasted Lisa's Java code into a PHP file, and then remangled it until it was executable PHP. Much of his frustration was rooted in the fact that her code didn't even run when he copy/pasted it into a PHP file. Somehow, that mangling had gotten it into a state where it could access the HelloWorldWS, which didn't have any authentication on it, but also broke the authentication code so that secure services wouldn't work."Um," Lisa explained, "my code is in Java. It's not PHP.""Java, so like, I can embed it into the front-end of my page? But wouldn't that mean putting the credentials into the HTML or JS files somewhere?"In the end, someone on Bert's team reached out to the vendor, who could point them to some PHP code examples for what they wanted to accomplish. It took a little longer, but Bert's team got what they needed. Bert, however, never quite understood what Lisa was talking about. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: Validly Numeric
Writing validation rules is one of the more tedious tasks a developer might need to do. Like testing code, it's all about finding edge cases, checking boundaries, and being exhaustive in your search for invalid data. Garbage in, garbage out, and validation filters the garbage.But you might also be a bit too thorough. Kevin found this validation rule in his C# codebase:
Error'd: Sick Day
How much longer will we endure wave after wave of novel coronaviruses? One school of thought holds that omicron or itsimmediate successor will soon burn its way through the human population and render everyone immune. So here is our entire stash of covid-related submissions before they get old, stale, and boring.Lonely Tim looking for love in all the wrong places, wails"I don't even count as a friend?"
CodeSOD: A Tern in the Stream
Java's streams feature allows developers to use functional programming techniques to operate on sets of data. Used correctly, it can create expressive and readable code. Used incorrectly, well…Gevatter Tod found this while searching for a bug.
CodeSOD: Exvention
For a lot of real-world situations, I'm a big fan of "event driven programming", or as I think about it, "bus oriented programming". Instead of coupling objects directly, objects just publish events to a shared bus, and the events get routed to the other objects which care about them, in a declarative fashion. It's not a "write all programs" this way sort of stance, it's just there are a lot of real world cases where I've found this to be very effective.Ricardo's co-worker seems to share my opinions, but perhaps maybe not quite my reasoning. This is the PHP code for handling checking out of their storefront:
CodeSOD: Numb to Truth
In the ancient times, philosophers asked the hard questions, like What Is Truth? And just when we might thing those questions have been answered, Uli brings us a new twist on an old classic."I found this while browsing an ancient C++ codebase," Uli writes.
CodeSOD: Two Addresses
When passing data over the wire, we frequently want to aggregate that data into a data transfer object. An ideal DTO lets a client get all the data they need in a single request, without needing lots of round trips to get related objects.Or, you could be like the contractors that Marty had to work with, and get handed this Java code:
Error'd: Time After Time
This week's submissions really aren't about time, they'vejust been sitting around a bit and need to get used up beforethey go bad. Or as the maestro used to say: "You might as well eat it... I'm only going to throw it away!"An anonymous reader waffles "I do want to answer but I'm only half sure."
CodeSOD: Three Links
Brian's hired a contractor to tackle a challenging technical problem: they wanted to display three links in three table cells. Now, you or I might just write that as HTML. But if we did that, we'd lose the opportunity to do this in JavaScript. Plus think of all that repetition- you'll be outputting a <td></td> tag pair three times. That's just wasteful.No, what we need is some elegant JavaScript solution that solves this problem without any unnecessary repetition.
Modernization
Micki worked for ConCom, a huge multinational development consulting company with offices on four continents. ConCom, in turn, assigned Micki's team to another multinational corporation, one that was looking for an ERP upgrade. Picture six developers in one little loft office, complete with dartboard, while the architects, POs, SMs, and the like were on another continent in a totally different time zone. At first they worked small tasks, proving themselves capable of being assigned the big upgrade project, and eventually, details started to come out of what the client really wanted.The current ERP was fairly unremarkable, if entirely dated. The bulk of the operations were scheduled jobs that processed CSV files uploaded from the branches to the central server. This system was what they intended to upgrade: ideally, with real-time messaging using a "top of class messaging broker and middleware." But the catch was, as always, they had to do the upgrade without any down time for the ERP system. So they had to do it in phases, one CSV at a time. Still, it should be an easy win, right? They would work on the branch side, and a central team would do the central server side. Easy peasy.But of course, nothing is ever that simple here at TDWTF.The first segment to be upgraded dealt with contracts. The branch would upload a "new contracts" file, and the central server would reply with a "processed and rejected contracts" file when it got done processing them. This all had to happen by 7:30 AM so that the information would be ready when the branch opened next. This should have been an easy replacement: both files had a well defined format, making it easy to create real-time communication around it.The catch? The central ERP knew nothing of CSV files at all. It only dealt with XML. So how were these files even being processed?As it turns out, there was another piece of software involved: a Java application from 1996, written by a developer who had long since retired, that handled the CSV to XML conversions and back. Thankfully, the source code was discovered, so they could at least read the comments. And try to search for the database it was using, since nobody knew it even existed, let alone where it lived.After weeks of studying and documenting how the ERP worked, suddenly, the development team were called (after hours) into a meeting with the PO, SM, Architects, Client Directors, and C-level execs. The project was touted as the "biggest project in the last 10 years" that would "save the company millions", and development would start tomorrow. The deadline? 3 weeks, or 250 man-hours. The entirety of their study findings had been ignored in favor of the "analysis" of an architect on another continent who never even spoke to the dev team, and never showed up again.But it was time to implement! And that meant setting up the message broker. Which the team had been given no details on, not even the name of the broker. When they complained, one of the developers was assigned to "remove all these blockers" instead of working on features. He tried; to his credit, he called just about everyone he could think of, signed a few NDAs, and attained a new security clearance. And he finally received it: a little documentation, access to the broker, and the message layouts. No documentation, no diagram, just the layouts; they had to guess how to map the CSV files to the message layouts they were given, as well as whether each one was a request or a response. They had incredibly helpful names, too: "AB", "ABC", "PB", "PBC", and "Rejected." It was clear what "Rejected" was, but the rest? They had to find out through trial and error that "ABC" was the reply to "AB" and the same for "PBC" and "PB."A few weeks went by—the project now officially late—and they got one more piece of information: there was a sixth message type, called "GC." Was this a message, since it had only two letters? Or a response, since it ended in "C?" Nobody knew. They assumed since it had a "C" they would receive it from the central server at some point, but they couldn't figure out the circumstances under which it would be sent. So they forged ahead, ignoring it, as you do.Another month of long, hard hours, and they were at the point where they could review and test the implementation. They provided AB and PB messages, based on the business rules to determine which would be sent, and expected a reply from the central server. This would be processed and displayed in a brand-new UI for the end user to review. So far, so good.Then it happened. The Call. The three-hour conference call with the central team to sync up on how to roll out the implementation. This is when new rules were discovered, including:
CodeSOD: Convenience
Casey works with some pretty courteous and forward thinking Python developers. They want to make sure that using their APIs are as convenient as possible, and make sure to provide all sorts of useful convenience methods. Like this one:
CodeSOD: Every Change
Now, I'm an old luddite who still looks askance at cloud services, but I'm willing to recognize their value. Still, I worry about whether I can trust that vendor to actually deliver the services I need, without them suddenly shoving out breaking changes which screw me, but maybe not their "whale" customers where the real money is.That's something which "Sleeper" got to grapple with last fall. They use Amazon's Athena service, which allows software to query S3 buckets using SQL syntax. Late last year, "Sleeper" got an email which they forwarded to us with the subject "This should be fun". The email started like this:
Error'd: Time Enough to Cry
Does anybody really care about time?Angela A. cares. "TGI(T|F)" she announces. "The days just run together!"
CodeSOD: Commentary
"Include descriptive comments for each method," isn't bad advice. I mean, ideally, the method name and parameters would be descriptive enough that you don't need to add lots of comments, but more comments is rarely going to hurt things. Unfortunately, "include descriptive comments" usually decays into "include comments". And that's how we get piles of code like this one, from Patrick:
Document Soup
An Enterprise Resource Planning system needs to keep track of your enterprise resources. Many of those resources, especially the expensive ones, need lots of documents tracked about them- inspections, service reports, maintenance bills, etc. So the ERP and the Document Management System need to talk.Years ago, for Coyne, this presented a few problems. First, the ERP was a mainframe application running on an IBM mainframe. Second, it was getting retired. Third, the DMS didn't talk directly to it, but instead communicated through a terminal emulator and used configuration files to correctly parse the screen contents coming back from the mainframe.The final, and key problem, was that, when examining the documents stored in the DMS, were that there were big confused piles of unrelated documents getting stored together. Specifically, if you looked for documents for the asset tagged 490, it'd fetch those, and also 49, 4900, 49000, or 490000. And vice versa, searches for 490000 would return all the other documents as well.Now, within the mainframe, the same data might get displayed on multiple panels. So, for example, the tag for a requisition document might be displayed in RQ01 on one panels, RQ02 in another, and RQ03 in yet another. And each of these fields could display the field differently, "depending on design, whim, programmer laziness and phases of the moon," as Coyne writes.
The Tech Lead
Years ago, Karthika was working as a contractor. She got hired on to develop an intranet application for a small government project. The website in question was already in use, and was absolutely mission critical for the organization, but it also had a very small user base- roughly five users depended on this application.When Karthika started, she immediately encountered a few surprises. The first was the size of the team- 8 developers, including a Team Lead. That seemed like a large team for that small number of users, and that didn't even include the management overhead. The code base itself was similarly oversized; while the product was important, it was a pretty prosaic CRUD app with a few tricky financial calculations involved.The core surprise was how awful the application was to use. It was slow to the point of sometimes timing out in the browser, even when running on your local machine. It was buggy, and even when Karthika patched those bugs, there was so much duplicated code in the system that the same bug would linger hidden in other screens for months. "I thought you said you'd fixed this," was a common refrain from the users.This was long enough ago that the UI was built in ASP.Net WebForms, but new enough that the data access was handled by Entity Framework. And it was one specific feature of WebForms that they were abusing that made everything terrible: UserControls.UserControls were designed to let developers create reusable widgets. For example a "User Information" screen may group the "User Name" and "Password" fields into a single "Credentials" UserControl, while the address fields would all get grouped together in an "Address" UserControl. That same "Credentials" control could then be dropped into other pages.When the user interacts with this data, Entity Framework can lookup a User object, hand it off to the UserControls, who allow the user to manipulate it, and then the controls can invoke the save on the User.The Tech Lead had encountered a problem with this. You see, he didn't want to share the same reference across controls because of "separation of concerns". So instead, each UserControl would create its own User object, populate it with database values, and then let the user interact with it. This meant when each UserControl had its own picture of the user object, and when it was time to save the data on the page, one control could overwrite the changes made by another control.So the Tech Lead invented CopyOldValues, a method which, during a save operation, would go out to the database, fetch the current data, and then compare it to the object being saved. Any NULL values in the object being saved would be updated to the database values, and then the object would be saved. This way, a UserControl could have a whole User object, but only populate the fields it was responsible for, leaving the rest as null. So yes, this meant that to save an object to the database, it required two round-trips to the database, per UserControl. And each page could have multiple UserControls.Karthika saw this, and put together a simple plan to fix this problem: just use the frameworks like they were meant to be used and cut this whole CopyOldValues nonsense out. She went to the Tech Lead and laid out a plan."This isn't an issue," he said. "You're wrong to be worrying about this. Stop wasting my time, and stop wasting yours. Instead, you should look into the date bug."So, Karthika tracked down the issue related to the date bug. Specifically, the database and the application were supposed to allow certain date fields to be NULL. But, since CopyOldValues used NULLs to decide which data to save, it was impossible to update a stored value to a NULL. Once again, the fix was obvious: just stop doing this weird intermediate step."Wrong," the Team Lead said. "That's totally not the correct way to do it. I have a better plan already."The "better plan" was to create a custom save method for each UserControl- of which there were hundreds. Each one of these would define an array which used the string names of each field it was responsible for, and then the object and the array would get passed to a new method, FindDifferences, which would use reflection to inspect the object, copy the updated values to a new object, and prepare to save to the database.The shocking end result of this, however, is that this made the application even slower. It didn't reduce the number of database round trips, and it added this whole reflection step which made accessing properties even slower. Despite only having five users, and running on a decently powerful machine, it was nigh unusuable. The Team Lead knew what the problem was though: the machine wasn't powerful enough.Strangely, however, throwing hardware at the problem didn't fix it. So the Team Lead invented his own caching solution, which made things worse. He started reinventing more wheels of Entity Framework and made things worse. He started copy/pasting utility functions into the places they were used to "reduce overhead", which didn't make things worse but made every developer's life demonstrably worse as the repeated code just multiplied.These problems made the customer angry, and that anger eventually turned into an all hands meeting, with representatives from the client side and the project manager as well. After the venting and complaining was over, the project manager wanted explanations."Why," she said, "aren't we able to fix this?"A round of blamestorming followed, but eventually, Karthika had to get specific and concrete: "We have a set of fixes that could address many of these problems, but the Tech Lead isn't letting us implement them and isn't giving us a good reason why we can't."The project manager blinked, puzzled. "Who? There's no defined tech lead on this project. You're a team of peers.""Well," the 'Tech Lead' said, "I… uh… have seniority.""Seniority?" the project manager asked, no less confused. "You started two weeks earlier, and that was just because you were the one contractor on the bench and we needed someone to knowledge-transfer from the outgoing team."The Project Manager had been overwhelmed by handling customer complaints, and hadn't been able to carve out time to attend any of the development team meetings. This meant that the Tech Lead's self-appointed promotion went unnoticed for eight months. At this point, the project was too far off the rails for any hope of recovery. The government office "fired" the contracting firm the next week, and all the developers, including Karthika, were fired from the contracting firm the week after that. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: Classic WTF: The Old Ways
Error'd: Up Up Down Down Left Right Left...
...Right B A. Right? Every so often, someone sends us asubmission with a hidden agenda. Of course we get the usualsolicitations for marriageable exotic beauties and offers totrade linkspam locations. But then there are the reallyinteresting ones. Maybe they're legitimate, maybe they'rephotoshopped or otherwise faked, and maybe they're an attemptto bypass someone's ban on political propaganda or quack science.In any case, there isn't any of that here this week, but we'resaving them up and maybe we'll feature a future issue of spotthe fraud for you.First up is dog loverGeorge with a hysterical spam-blocking email address, sharinga help message that must have been crafted by Catbert himself."My sixty seconds of glory awaits!" he howls, but then whimpers"I will be real disappointed if the agent isn't[Gone in Sixty Seconds headliner] Nicolas Cage."
CodeSOD: A Pointer to your References
John C works at a defense contractor, and his peers are well versed in C. Unfortunately, many years ago, a lot of their software started being developed in Java. While references are often described as "pointers, but safer," they are not pointers, so your intuitions about how memory gets allocated and released are likely to be wrong.Which is definitely the case for John's peers. For example, in C, you generally want really clear understandings of who owns a given block of memory. You don't want to allocate memory and hand it off to another module without being really clear about who is responsible for cleaning it up later. This means that you'll often write methods that expect buffers and other blocks of memory passed into them, so that they don't have to worry about memory ownership.Which is how we get this block of code:
A Basic Print Algorithm
In the late 90s, Aaron was employed at a small software company. When his coworker Mark submitted a letter of resignation, Aaron was assigned to maintaining the vast system Mark had implemented for an anonymous worldwide company. The system was built in the latest version of Visual Basic at the time, and connected to an Oracle database. Aaron had never written a single line of VB, but what did that matter? No one else in the company knew a thing about it, either.Before Mark parted ways with the company, he and Aaron traveled to their customer's headquarters so that Aaron could meet the people he'd be supporting and see the system perform in its live environment. A fellow named Boris met them and gave a demo at his cubicle. At one point, he pressed the Print button to print out a report of certain records. After some serious hourglassing, the system displayed a dialog box asking, Do you want to print page 1?, with Yes and No as options. Boris chose No.More hourglassing. Do you want to print page 2?And on it went. Not only did Boris have to choose Yes or No for every page, the time to display each prompt was ridiculous, anywhere from 30 to 90 seconds per page.By the time they crawled to page 30, Aaron was dying inside and could no longer restrain himself. "Why is it like this?!" he half-asked, half-accused Mark."The customer wanted it this way," Mark replied, either unaware or indifferent to his coworker's frustration."This is the way we want it," Boris chimed in. "We don’t always want to print every page. Sometimes we just want one page, could be page 73.""But why not give one prompt where the user can type in the specific pages they want?" Aaron asked."Is that possible?" Wide-eyed, Boris turned to Mark. "You told us it wasn't possible!""It isn't," Mark said with conviction.Aaron flushed with embarrassment. He assumed he'd put his foot in his mouth in front of an important customer. "Sorry. You're the expert."Still, the issue niggled at Aaron long after they returned from the customer's site. Once Mark had packed up his cube and departed for good, Aaron tracked down the report-printing code. He found a loop that started off something like this:
CodeSOD: The Correct Browser
Sometimes, it's not the code that's bad, but what the code costs. For Elizabeth's company, that cost was significant in terms of dollars and cents. They needed to staff up to accomplish some major Java Enterprise work, so they went with the highest of the highly paid consultants they could find. These consultants came from a big name firm, and were billed at an eye-watering hourly rate.Elizabeth warns us that the Java code is a behemoth of WTFs that is "too difficult to describe", but one particular WTF leapt out at her. Specifically, included in the application was a file called nonIEUser.html. This project was happening circa 2012, which is after Microsoft finally admitted standards might need to be a thing, and definitely well outside of the time when your web application should only work in Internet Explorer. For a greenfield project, there was no reason to do anything IE only, and fortunately, they didn't- aside from forcing a check to yell at you if you didn't use IE.This is the error page that it would display:
The New Management
For a young college graduate in the early 80s, Argle was fortunate to already have some real-world experience. That served him well, because businesses which were looking towards the future were already looking into how they could improve their automation with the new and relatively cheap computer systems that were hitting the market.One such company was a family-owned, multi-generational manufacturing company. They had a vision for the future, and the future involved the latest in CNC milling machines and robotic manufacturing. They needed the team that could send them into the future, and were hiring to build that team.Argle was one of those hires, brought on as a junior developer. His mentor, Stanley, was an old Texas Instruments guy who had helped design many of the chips that were driving the fancy robots. Stanley leaned into his mentor role, both in terms of being a good mentor, but also in terms of the aesthetic: he was a bearded pipe smoker in a tweed jacket with patches on the elbows, and a pocket protector loaded with pens and a compact slide rule.For a small manufacturing firm, the owner was happy to invest in this team. He brought on vets from JPL or mechanical engineers who had helped automate German auto plants. The owner himself heavily recruited from the same college that Argle attended, giving talks about the future of automation and reinforcing his company's commitment to the future. Interns and junior developers bulked out the team.The owner walked the walk, talked the talk, and was putting money where it needed to go. The job was an absolute delight for Argle and the rest of the team. He learned a lot from Stanley, and also from the work itself.And then, one day, the owner introduced Gordon. "This, is our new President, Gordon. He'll be handling the overall operations of the company while I focus on our vision and direction."Now, for most employees, the introduction of Gordon was barely worth commenting on. New management slotting into leadership positions was just background noise and didn't really impact the work. Except for Argle. Argle actually knew Gordon, at least by reputation, because Gordon was the VP at the local public broadcasting company.Now you might wonder, "how does experience in broadcasting help someone oversee a manufacturing company?" Well, Argle had the inside scoop on exactly how Gordon would lead. Argle's father worked at the local PBS affiliate, and had regaled Argle with all sorts of stories about Gordon's style. That style was a blend of bullying and cronyism.Now, up to this point, Argle's team had acted more or less like a leaderless collective. They all had a goal, they all understood the goal, and they all pushed together to achieve the goal. There was no manager. They'd defer to the senior members on matters of disagreement, but even then it was never "Stanley said so," and more "Stanley will explain this so everyone comes to an agreement."That, of course, couldn't stand under Gordon's leadership. So Gordon hired Dave to provide management. Like Gordon, Dave also had no background in manufacturing, technology, automation or robotics. Or, in actuality, project management, as Dave illustrated in his first project meeting.As this was the 80s, the conference room was a nicotine stained room with a transparency projector. Stanley sat in a corner, puffing away at his pipe. Dave had a stack of transparencies and a red dry erase marker to scribble on them with."So, Stanley," Dave said as he slapped one of the estimates Stanley had assembled onto the projector. "How long did you think this effort would take?"Stanley pointed his pipe stem at the numbers Dave was projecting. "An effort like this will take a year.""That's much too long," Dave said. "I was looking this over, and you had 6 weeks for milling these parts, but I think we can outsource that and get them back in three weeks. I have a vendor already committed." Dave edited the numbers with his red pen. "And then development time, you've got poor Argle booked for six months, after the hardware design is finalized, but we can start development earlier than that…"People around the room started raising their objections. Dave had no time for these naysayers. "You would think that, but you haven't even finished with college," he told an intern. "Maybe things worked that way at JPL, but we live in the real world here." "If TI was such a good company, you'd probably still work there- either they suck or you're an idiot."By the time Dave finished his tirade, he had individually insulted everyone on the team, and had cut the project time down to six months. "You see? We can totally do this project in six months."Stanley took a few puffs of his pipe and said, "You can say it will take six months, but it will still take a year."As Dave started piloting the team straight into the ground, Argle got an offer. A few of his college friends had moved out to another state, launched a startup, and were offering him a 40% wage increase plus moving expenses. Add into the fact that Dave had explained that nobody on the team would be eligible for a raise for five years, Argle was halfway out the door.But only halfway. Argle was young, still had some optimism, and wanted to be loyal to his team, even if he wasn't loyal to the company. So he talked it over with Stanley."I like this team, and I like the work that we're doing, and I'd hate to leave the team in a lurch."Stanley puffed on his pipe, and then answered. "The company will be sad to see you go. I'll be sad to see you go. But the company could lay you off tomorrow, and they'd be just as sad about it too. But they'd do it if they thought it was necessary. You don't owe this company anything more than that."So Argle submitted his notice. By coincidence, it was on April First, which Dave tried to use as an excuse to bully Argle into feeling guilty about either a bad prank or bad timing for quitting. Dave wanted to make a counter offer, but he couldn't do it without insulting Argle on the way to offering him a raise, which made Argle's choice very easy.Two weeks later, he was loading a truck with all his worldly possessions, and two weeks after that he was settled into a new house, and a new job, and even happier than he'd been at the manufacturing company.Over a year later, Argle went back to visit family, and swung by the old company to see how the team was doing. Stanley was still there, but Dave and Gordon were long gone. The owner was fooled for a bit, but was too smart to stay fooled. Dave and Gordon were out the door only a few months after Argle left."So," he asked Stanley, "how'd that project go? How long did it take?"Stanley puffed on his pipe and chuckled. "Oh, about a year." [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Error'd: Everything Old is New Again
Whenever there's a major change in the world, it always takes applicationdevelopers a little time to adjust. Remember when the US governmentthought it would be a great idea to mess around with their Daylight Saving Timeschedule with only two years warning? (I'm guessing nobody remembers the fiddlingdone by earlier administrations because they were too young to care, ornot born yet.) Two years warning probably seemed like plenty to non-technicallegislators, not thinking about all the software that was in place with built-in calendars.Well, someone has apparently decided to one-up a measly time change, by inventing somethingcalled a New YEAR. This resets the entire calendar, and it must be a novel practicebecause surely websites wouldn't break due to some routine event that has been happening for at least a dozen years or more, right?Right?Aspiring Poké trainerValts S.began a long long time ago far far away.
CodeSOD: Well Trained
Mandatory compliance training is a thing. The reasons behind it range from companies trying to reduce civil liabilities to actual legal mandates which require the training. The quality of mandatory training ranges from "useless" to "actively awful", and it's mostly PowerPoint-style slides interspersed with quizzes to make sure you were "paying attention". The worse ones will usually have timers on the slides so you can't just click past, and have to actually idle to "force" you to read it.Also, since legal compliance tends to move slower than technology, training built years ago is frequently still relevant. So, for example, Duncan's company built training back when you could reasonably expect Flash to run in the browser. Building the training and the content cost money, so once Flash got deprecated, they weren't just going to throw that money away- they found a contractor who'd convert it to "HTML5".Now, this means that the code quality is garbage, which is fine. We can't really fault the tool. But there are some assumptions about the very use of the tool that render these quizzes even more useless than the usual fare:
CodeSOD: Do Nothing
Ivan encountered a strange bug. His organization uses the R language, which has a handy-dandy documentation language attached to it, for Rd files. The language itself is an organically grown hodge-podge of R and LaTeX, built to make it easy to format both plain text and R code within the documentation. It lets you use LaTeX-like commands, but also mix in R code to control the output.Ivan's problem was that one of his macros, which we'll call \mymacro, only worked sometimes. The specific cases where it failed were where the macro expanded into multi-line output, which once upon a time wasn't a thing that Rd supported, but is supported, and clearly wasn't the problem. Ivan poked at it from that direction, suspecting there was maybe a regression, and then spent a lot of time trying to understand the places where the macro did and didn't work.It took some time, but eventually the key difference was that the pages that worked also called another macro, \doi{}, which itself called \Sexpr[stage=build]{...}. Now, there's one important thing to note about the \Sexpr macro: it's meant to invoke R code inside of your documentation. And that made all the difference.The documentation which didn't contain R code would be stored as a raw documentation file in the package. Before rendering the documentation, the parseRd tool would need to parse the file and generate the documentation output. This would happen after the package was built and distributed. Since the \mymacro might expand into nothing, this was technically unparseable at that point, and would cause the documentation render to fail.On the other hand, documentation which did contain R code would be parsed and the parse tree would be stored in the package. There would be no parse step when the documentation got rendered. The whole "expanding to nothing" problem didn't exist in this situation.So the fix was obvious, at least to Ivan:
CodeSOD: Cloudy Optimizations
Search engine optimization is both a dark art and a corrupt industry. Search providers work hard to keep their algorithms opaque. SEO is a mix of guessing and snake oil and sometimes outright lying.For example, Mark M recently inherited a rather… bad PHP website. One of its notable SEO tweaks was that it had a tag cloud that slapped a bunch of keywords together to give a sense of what kinds of articles had been posted recently. At least, that was the idea. But when Mark dug into the code, there was no sign that there was any source of tags in the database. In fact, articles didn't get tagged at all. So where was the tag cloud coming from?
My Many Girlfriends
In the long ago, wild-west days of the late 90s, there was an expectation that managers would put up with a certain degree of eccentricity from their software developers. The IT and software boom was still new, people didn't quite know what worked and what didn't, the "nerds had conquered the Earth" and managers just had to roll with this reality. So when Barry D gave the okay to hire Sten, who came with glowing recommendations from his previous employers, Barry and his team were ready to deal with eccentricities.Of course, on the first day, building services came to Barry with some concerns about Sten's requests for his workspace. No natural light. No ventilation ducts that couldn't be closed. And then the co-workers who had interacted with Sten expressed their concerns.During the hiring process, Sten had come off as a bit odd, but this seemed unusual. So Barry descended the stairs into the basement, to find Sten's office, hidden between a janitorial closet and the breaker box for the building. Barry knocked on the door."Sten awaits you. Enter."Barry entered, and found Sten precariously perched on an office chair, removing several of the fluorescent bulbs from the ceiling fixture. The already dark space was downright cave-like with Sten's twilight lighting arrangement. "He welcomes you," Sten said."Uh, yeah, hi. I'm Barry, I'm working on the Netware 3.x portion of the product, and Carl just wanted be to check in. Everything okay?"This is acceptable to Sten," Sten said, gesturing at the dim office as he descended from the chair. Sten's watched beeped on the hour, and Sten carefully placed the fluorescent bulb off to the side, in a stack of similarly removed bulbs, and then went to his desk. In rapid succession, he popped open a few pill containers- 5000mg of vitamin C, a handful of herbal and homeopathic pills- and gulped them down. He then washed the pills down with a tea that smelled like a mixture of kombucha and a dead raccoon buried in a dumpster."He is pleased to meet you," Sten said, with a friendly nod. Barry blinked, trying to track the conversation. "And he is pleased with it, and has made great progress on building it. You will like his things, yes?""Uh… yes?""He is pleased, and I hope you can go to him and tell him that he is pleased with this, and set his mind at ease about Sten."So it went with Sten. He strictly referred to himself in the third person. He frequently spoke in sentences with nothing but pronouns, and frequently reused the same pronoun to refer to different people. The vagueness was confounding, but Sten's skill was in Netware 2.x- a rare and difficult set of skills to find. So long as the code was clear, everything would be fine.Everything was not fine. While Sten's code didn't have the empty vagueness of unclear pronouns, it also didn't have the clarity of meaningful variable names. Every variable and every method name was given a female first name. "Each of these is named for one of Sten's girlfriends." Given the number of names required, it was improbable that these were real girlfriends, but Sten gave no hint about this being fiction.There was some consistency about the names. Instead of i, j, and k loop variables, you had Ingrid, Jane, and Katy. Zaria seemed to be only used as a parameter to methods. Karla seemed to be a temporary variable to hold intermediate results. None of these conventions were documented, obviously, and getting Sten to explain them was an exercise in confusion.It led to some entertaining code reviews. "Michelle here talks to Nancy about Francine, and then Ingrid goes through Francine's purse to find Stacy." This described a method (Michelle) which called another method (Nancy), passing an array (Francine). Nancy iterates across the array (using Ingrid), to find a specific entry in the array (Stacy).Sten lasted a few weeks at the job. It wasn't a very successful period of time for anyone. Peculiarities aside, the final straw wasn't the odd personal habits or the strange coding conventions- Sten just couldn't produce working code quickly enough to keep up with the rest of the team. Sten had to be let go.A few weeks later, Barry got a call from a hiring manager at Initrode. Sten had applied, and they were checking the reference. "Yes, Sten worked here," Barry confirmed. After a moment's thought, he added, "I suggest that you bring him in for a second interview, and have him walk you through some code that he's written."A few weeks after that, Barry got a gift basket from the manager at Initrode.
Error'd: Fin
At the end of the year, it's customary to reflect on the past and imagine a future.Here at Error'd, reflecting on the past is natural, but all we can do about the future is hope.So to close out the longest 2020, here are a handful of little muffed missives.Occasional contributorPeter diagnoses a counting error."Looks like the web server had a thing or two to add to the discussion."
Best of…: Best Of 2021: Totally Up To Date
Best of…: Best of 2021: The Therac-25 Incident
...11121314151617181920...