The Daily WTF

Error'd: Where I Come From, We Don't Need July

"Someone FINALLY got it right!!" Farz wrote, "In my native language, we don't have translations for seven months out of the year. Way to go Windows Live!!"

 

"I know Dell is supposed to be going private, but I didn't know that it would be up to me to keep them afloat!" writes James Helms.

 

Ben N. sent in the following screenshot whilst shopping online. I bet some pun minded categorizer at Amazon thought that having a BOLD cup of coffee sounded REALLY good at the time.

 

"Developer's excuse for screwing up #439: Sorry, I was eating a milky way, so I forgot to fix any issues with the feed." wrote Chris M.

 

Wilt writes, "I know the budget is tight, But even if it wasn't, I don't think I could justify NVIDIA at that price."

 

"I'm fine that Thirstin Howl's track Spit Boxer isn't on Spotify," writes Nick, "but their suggestion wasn't quite what I was expecting."

 

"Things aren't looking so good for being able to read 'Fine Cooking' on my iPad," wrote Jeff.

 

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Fire Rescue, Troubled Widgets, and Other Support Stories

The company that Karl J. works for recently signed a contract with a big North American corporation and everybody’s really excited at the prospect. Practically overnight, their flagship product - a platform-as-a-service solution – would gain a boost of about 40,000 users and an accompanying in-stream of cash too.

But there was one detail that made everybody, well mostly management, feeling nervous: their client insisted on having 24/7 support. But, you know what? That’s OK! Karl’s employer hired a 3rd party agency to do the grunt work of front-line support and escalate non-trivial issues when they would arise, around the clock.

Services were purchased and that money was used in turn to purchase even more services to keep it all running smoothly. Unfortunately, the 24/7 support agency proved to be less capable than originally anticipated. Or perhaps somebody forgot to tell them that what they actually did.

===========0006401801================= Fri 05-Apr-13 01:56p ====================================== NAME:Tim COMPANY:abbotsford fire rescue PHONE:604-123-4567 "Based on your service agreement with NACK/Fuzzbin, is this a high, medium, or low severity? If you are not sure, we'll assume its either high or medium and contact the on-call now" SEVERITY: HIGH[x ] MED [ ] LOW[ ] NOTES:198 Emerson St, SomePlace Electrical system has been compromised. fires from electrical. "Thank you for calling an on-call technician will contact you as soon as possible." -------------------------------------- Message History Account: 63101234 Taken: Fri 05-Apr-2013 1:54p UN Serial#: 1 ===========0006401801=================

It's Too Windy! (from Jeff W.)
"Man, I guess that when it picks up out there, the wind sure can blow those loose bits around!"

 

Troubled Widgets (from Dean)
A while back, Dean's wget requests started failing for no apparent reason. So, he submitted an incident to his local IT staff to try and get wget pushed through the firewall, some how, some way.

Here's the text of the incident:

I just recently my wgets have started failing. firewall issue? wget -P . 'http://ftp.drupal.org/files/projects/read_more-7.x-1.x-dev.tar.gz' --2011-11-11 11:46:05-- (try: 2) http://ftp.drupal.org/files/projects/read_more-7.x-1.x-dev.tar.gz Connecting to ftp.drupal.org (ftp.drupal.org)|140.211.166.134|:80... connected. HTTP request sent, awaiting response... Read error (Connection reset by peer) in headers. Retrying.

So a few days later, someone from IT (who just happened to be the CTO) came to Dean's desk to help with my issue, in person. The first words out of his mouth? "So, tell me, which widgets are you having troubles with?"

HP Support Gives Me the Warm and Fuzzies (from Dan H.)
DanH : I'm trying to get this printer, and a P1505n, set up on a Linux print server (for evaluation purposes), but hppi diagnostics doesn't recognise them. There are no firewalls in the way, as I successfully tested a 2500 series printer last week. ** An agent will be with you shortly. ** ** You are now chatting with HP_bod . ** HP_bod : Welcome to HP Total Care Chat Support for Imaging & Printing Group. My name is HP_droid. Please give me a minute while I review your problem description details. DanH : Ok, thanks. HP_bod : DanH, as I was reviewing your details, I came to know that you are using HP Color Laser Jet CP1515n Printer connected to a computer with operating system as LINUX and you are facing issue as you are not able to install your printer on your computer. Am I correct? DanH : Mostly. :) I've installed the model scripts, but the HPPI utility can't complete the networking check on these printers. HP_bod : DanH, I greatly appreciate that you have forwarded your concern and have given us a chance to assist you on this matter. HP_bod : As a consumer myself, I can certainly understand your frustration. HP_bod : I, on behalf of HP Technical Support take the ownership of this issue and will try to resolve this issue to the best of my abilities. DanH : Thank you. HP_bod : You are most welcome, I am here to assist you. HP_bod : DanH, I would like to inform you that you are trying to install the driver of your printer from the CD which came initially with the Printer, the drivers in that Installation CD are on compatible to the Operating System as Windows XP. HP_bod : I will assist you but before that I need your confirmation of the above mentioned statement? DanH : I'm not trying to install the drivers from the CD. The printer server is a linux operating system, so I got the model scripts from HP in the internet. HP_bod : Ok. HP_bod : DanH, I would like ot inform you that we do not have the correct expertise on the Operating System as Linux. [Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Cheaters Never Prosper

"That's quite an impressive resume, Fred," Avi said. The phone interview had gone well so far; among the several hundred applicants for Senior Developer at BigBoxCo, Fred's qualifications put him among the top five Avi had spoken to. Fred himself was amiable, if slightly over-confident.

"Thanks, Avi," Fred replied. "I hope I have what you're looking for."

"Regarding your last position at IniTech," Avi said, "which ended about six months ago, why did you decide to leave? It looks like you'd be taking a step down working for us, since you were the project lead on their flagship software."

"Well, management didn't care for my coding style," Fred said. "I write fast, test faster, and iterate often. More agile than Agile, you might say."

"I might." Avi decided to see what Fred's "coding style" looked like. "Okay, I'm going to establish a guest session on our collaborative IDE. Just type in the URL I give you, followed with the session token."

"URL?" Fred sounded affronted.

"Yes, the address to access the session."

"I, um. . . well, okay."

Avi spelled out the URL and session token, but Fred couldn't seem to figure it out. Finally, Avi just emailed the URL to Fred's address. "Oh, got it now," Fred said.

Avi sighed. "Okay, I'd like you to write a function that merges two integer arrays of arbitrary length. Don't worry about performance for now."

Immediately, a piece of code flashed into the IDE. "Okay, done," Fred said.

The jig was up. "Fred, where did you copy this from?" Fred wasn't getting that Senior Developer position, but Avi wanted a confession before the interview was over, if just to satisfy some need for justice.

But Fred wasn't forthcoming. "I just typed it all right now. Look, you can run it if you'd like--"

"Fine, Fred," Avi interrupted. "Then how would you change this to avoid duplicate entries?"

"Oh, just change that one there to a negative one." Fred's voice faltered.

"What one, there's no--" Avi said, before he spotted a lowercase l, which looked like a 1 in the IDE, twelve lines down. "Okay, we're done, Fred," Avi said, hanging up before Fred could sputter another word.

Although he wouldn't get a confession from Fred, Avi wanted to see where the code came from. He ran a simple search with the idiosyncratic method signature. The first result was a Stack Overflow question. Typical, Avi thought, just before he opened the page and saw the truth: the code came from the question itself, not one of the answers. The code would never have compiled, much less run.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Announcements: England DevOps Talks/Workshop and a London Meet-up

I'll be heading to England next week to talk about DevOps and Cloud Stuffs.

London Get-together!

Who's up for a pub nite? I'm thinking somewhere in London on Friday, May 24 and/or Saturday May 25. If you're up for getting together for some dinner and drinks, please drop me a line and we'll figure something out. And hey, first round's on me!

##
Update: Whoops! I meant May, not June!

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

CodeSOD: A Cascade of Failure

Ben sent in the following snippet from a PHP site. His description of the site as a whole is unpublishable in most countries, but among his frankly shocking profanity he pointed out a lack of error checking and comments, and an abundance of unreadable inline code and confusing, unnecessary functions.

When Ben tried to describe the following routine though, he broke down, weeping openly. While we wait for him to regain his composure, let's ponder the depth of wrong present in this code:

<style type="text/css"> .file_1 { height:26px; float:left; background:url(../images/input2.png) left top no-repeat; width:188px; border:0px solid #A7A9AC; font-family:Arial; font-size:12px; color:#4a4a4a; font-weight:normal; text-align:left; } <?php for($i=0;$i<count($FileClassArr);$i++) { ?> .<?php echo $FileCLassArr[$i]?> { height:26px; float:left; background:url(../images/input2.png) left top no-repeat; width:188px; border:0px solid #A7A9AC; font-family:Arial; font-size:12px; color:#4a4a4a; font-weight:normal; text-align:left; } <?php } ?> </style>

That's right, every file gets its own CSS class. And, just so none of the files get jealous of each other's classy style, they're all exactly the same! Why wouldn't you just define one class and apply it to every file's HTML element? We'd ask Ben if he discovered the original developer's rationale, but we don't want to set him off crying again.

There, there, Ben. We're misting up a little bit on your behalf.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Trust Your Instincts

I'm not looking for a new job, but a head-hunter called (from a five year old resume) with a position that sounded pin point perfect. Since there is nothing going on at work, I thought I'd check it out.

At the interview, I met some mid and senior level developers, and the team lead. They asked the usual technical, problem solving and how-would-you-x type of questions. I answered fairly well, and established a decent rapport while trading war stories. They seemed to feel the same way, as they grabbed the manager to chat with me afterward.

I spent about 30 minutes answering higher level architectural, support and management type questions. Then he asked me something for which I was completely unprepared.

"Do you ever read The Daily What-the-F***?"

"Um, sure; I read it often! Why?" (my fault for asking)

"Have you ever read any articles by 'snoofle'?" (uh oh; where is this going?)

"As a matter of fact, I have; why do you ask?" (again my fault, I was flustered)

"What do you think of the way he seems to deal with incompetent co-workers and management?"

(How to proceed?)

"I think he accepts that IT is there to support the business, and that you can't always do things the 'right' way; but it's important to ensure people understand the cost of running up a technical debt. Then try to gently nudge them in the right direction. What do YOU think of him?"

He generally agreed. I sensed an opportunity: "What would you do if snoofle walked in here, sat down in this chair, handed you a resume and asked to be considered for this position?"

"I'd hire him outright!"

"Without tech'ing him out?"

"Yes; I know the type from his writings."

"What if he and I were both sitting here?"

"I'd probably go with snoofle..."

"(With a smile) Even though your team has already decided I'm a keeper?"

"I think so, but you're here and he isn't..."

I asked if I could use his PC to show him something, opened up a browser, went to TDWTF, logged in as snoofle and showed him. After a moment, his eyes bugged out...

Shortly after the interview ended, I got a call from the agent: "Congratulations; you got the job!"

That night, something about the manager's willingness to blindly hire an unknown entity started to bug me. I don't know why; it just did. The next day, I begged off and declined the position.

Naturally, the agent gave me the hard sell, but then I got a call from the hiring manager...

"Why did you turn us down?"

I explained my uneasiness with his willingness regarding an unknown entity, and politely thanked him for his time and consideration.

After some futile pressure on his part, he continued (hesitatingly): "You know, I can tell folks your real name..."

To myself: What the... did he just threaten me?

I told him there was nothing I could do to stop him, but if he did, then I'd be completely justified in posting all over the Internet about his threat - identifying him by company, department and full name. Then I advised him to let it go. Then I hung up.

Interviewing is something of a soft scientific/artsy kind of process, but when all is said and done, trust your instincts.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Error'd: What's This?

"I just wanted to know what a certain pending charge meant on my credit card, unfortunately the help text popup didn't know either," writes Alex N.

 

"I was looking at a mortgage prepayment calculator and after entering the terms of my current loan, the usual ads about how much I could save popped up," wrote Tawnos, "Not only would I get to pay closing fees, but I'd pay more every month!"

 

Mark G. writes, "Sorry Facebook, I don't go hanging out in graveyards any more than you do."

 

"Guess I'd better hurry and do my transaction before the...battery runs out?"Steve T. wrote.

 

"I had a crazy idea that I might want to buy some HP ink," writes Ari Stinik, "Seems I'm mistaken."

 

"Apparently, according to Twitch TV I was born on the first of español, 1980. At least they got half the language properly translated." writes W. Espinosa.

 

"You don't get to look this good for peanuts indeed!" remarked Bas van der woude.

 

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Slacking Off

“It’s a small, dynamic company.” “We’re growing, and growing fast!” “Our agile team needs some strong management, and we think you’re right for the job.” “Your paycheck is going to be so large Ed McMahon will deliver it.”

Michael had heard this pitch before, but this time, he decided to take the position. The IT director, Lisa, had her head on straight and a clear vision for what she wanted from Michael and his new team. Those eight developers and eight testers had languished without any meaningful oversight for the better part of a year. The result: a team behind schedule, over budget, and the best developers fleeing for better prospects.

With Lisa backing his decisions, Michael waded into the muck, protected by confidence. He started the cleanup process with one-on-one sessions with everyone on the team. Jeffery was cheerfully optimistic about their prospects. “I’ve only been here six months, but I’ve seen a big turn-around. Our last sprint delivered its targets, and with fewer defects than ever.”

Larry, the senior-most developer, saw a far more dire future. “I’ve gotta be honest, I think we’ve been too micromanaged the past few months. Jeffery knows how to play politics and avoid doing any real work. The entire time he’s been here, he’s gotten management to help him avoid work.”

The rest of the team agreed with Larry. Jeffery wasn’t a slacker, but an active obstacle who worked to erect barriers to the central goal of getting things done. Michael knew that this would be a serious problem in the long run, so he scheduled some extra time with Larry to get to the root of the problem. What was Jeffery doing to hold the team back?

Pleased to be the center of attention, Larry explained. “For starters, Jeff refuses to touch the code. Just refuses.”

“Interesting, because he’s done the most check-ins during the past month.”

“Oh, check-ins, sure. Him and that cockamamie source-control stuff. It’s a great way to look busy when you aren’t actually doing any work. We’re running ourselves ragged, working right on the production boxes.”

“You… you change live code?”

“That’s right,” Larry said. “We’re serious around here. ‘Performing without a net’, as I like to call it. ’Course, now, we’ve got to put everything through source control or Lisa comes storming down here in a fit. It’s a real pain.”

“I see… and what else has Jeffery been doing?”

Larry spent a moment in thought. “Well, here’s a good example- we needed to make some changes across all 25 customer databases. And Jeffery refused to do it.”

“Refused?”

“Refused. He wanted to write a script, then he wanted to spend a few days testing the script in DEV and STG. Ain’t nobody got time for that. I went ahead and made the changes myself.”

Larry happily went on, listing Jeffery’s vile sins against productivity. Jeffery was unsatisfied with the efficient system of tracking defects by word-of-mouth and the odd email; he demanded an actual defect tracking system. Jeffery wanted to use continuous integration and waste time writing unit tests for vital modules. His worst sin of all was refusing to sign off on releases with easily exploitable SQL injection vulnerabilities. “Our end users just aren’t smart enough to know how to exploit them, anyway. It’s such a non-issue.”

Michael sat down with Lisa, and laid out his opinions on this conflict: Larry, not Jeffery, was the biggest obstacle to team success.

Lisa agreed. “Larry wouldn’t know bad code if it lodged in his anus and threw a noisy party.” Together, they made Jeffery the team lead and moved Larry towards an infrastructure role.

Things turned around. The burndown chart fell faster than Facebook’s stock price. With management support, Jeffery put even more effort into helping the team be successful. He volunteered lunchtimes to teach the others how source-control helped them. He worked extra hours adding unit tests. After ten weeks, they were close to a shippable release.

After eight weeks, however, the money ran out. Their initial release target dates were so far in the past only archaeologists were interested in them. Investors and creditors asked uncomfortable questions about their money. Upper management did what upper management always does when money is tight: cut costs. Michael and Lisa, as management overhead, went out the door first. Jeffery, who was the newest developer and who negotiated a great starting salary followed them.

Larry had been with the company since the dawn of time. Larry hadn’t seen a raise in six years. Larry cost little. Larry not only kept his job, but was promoted to fill the management vacuum. Now, he had to do the jobs of Michael, Lisa and Jeffery on top of his usual work. Larry had no fear, because he had some ideas for making the team more efficient. The first thing he did was get rid of that pesky source control system…

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

CodeSOD: Re-Inventing the Alphabet

Michael listened as his co-worker Draughon droned on at lunch. "I just don't trust hashes, man. I never understood any of the algorithms behind them, and I don't trust anything I don't understand."

"But MD5 is a well-documented algorithm," Michael countered.

"Nonsense," Draughon said. "Just try reading the documentation. It's a little better if you do it stoned, but company policy frowns on that, doesn't it?"

Michael nodded, not that he had to worry from IniTech's random drug screenings.

But Draughon should have. Shortly after lunch, Michael's coworker was escorted out by security, and his desk -- filled with rolling papers, but no illicit substances -- was swiftly emptied out. Michael's inbox was flooded with assignment notices as Draughon's ticket queue emptied out onto Michael's.

Before Michael left for the day, he decided to check one of the tickets, curious if Draughon's paranoid coding strategy actually worked. The client wanted to replace an .mp3 file uploaded with a tool Draughon had written, but they couldn't find the file name in the public directory. After FTP-ing onto the server, Michael found tens of millions of files named si4md, 7r0s2, etc. Michael found the tool Draughon wrote in the IniTech repo, including one peculiar function:

public static string GenerateFilename() { string valid_chars = "abcdefgijkmnopqrstwxyz1234567890"; string temp = string.Empty; Random r = new Random(); for (int i = 0; i < 5; i++) temp += valid_chars[r.Next(valid_chars.Length)]; return temp; }

"Don't like hashes, huh, Draughon?" Michael said, smirking. The function was run whenever a file was uploaded, generating new files even when the original was being over-written. He considered it lucky that there hadn't been a file name collision, with tens of millions of files and counting being uploaded with the tool. He replaced the naming scheme with an MD5 hash of the original file name.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Irregular Regular Expressions

Marcus A. worked for a man who believed that regular expressions were the be-all end-all and could be used to trivially solve every data problem that could possibly arise. Their code base was riddled with regular expression transformations that would reduce most developers to tears. This manager also believed that anything that could be explained could be implemented more cheaply offshore.

Their main application contained a raw text field that held comments by customers. Someone got the idea that these comments could be mined and used for business purposes. However, to do this in a free format text field, the non-standardized words and phrases used by humans would need to be cajoled into something that was more easily processed. To this end, Marcus was tasked with managing an outsourced effort to standardize this data. The input would be a Customer Data table with a comments column. The output would be the same column, but with abbreviations, acronyms, etc. converted to standardized text.

To prepare for outsourcing, an aide manually searched the myriad rows in the database for a list of such acronyms and abbreviations, and transcribed it into an Excel spreadsheet. There were more than 1,000 items, all specified in all the usual ways folks might abbreviate them:

Old Content New Content ---------------- ----------------- "IRS" Internal Revenue Service " IRS " Internal Revenue Service "I.R.S." Internal Revenue Service "irs" Internal Revenue Service "i.r.s." Internal Revenue Service "I R S " Internal Revenue Service "FBI" Federal Bureau of Investigation " FBI " Federal Bureau of Investigation ... "DR" Doctor "dr" Doctor "dr." Doctor " dr " Doctor ... "off" Office ... "fnf" FILE_NOT_FOUND

A work scope document was prepared, contracts were bid, and the work was shipped offshore to a coder named Rahul.

Now Rahul could have realized that this could be generalized, and implemented a relatively short solution using some lists of strings and a couple of loops. Or he could blindly implement exactly what was requested. The resulting code that was turned in consisted of hundreds of brute-forced procedures that all looked like this:

String sourceRegularExpression = "IRS"; // OP: hard coded in every function for each of the values String targetRegularExpression = "Internal Revenue Service"; String query = "select id,comments from CustomerData where comments like '%" + sourceRegularExpression + "%'"; Connection con = ... PreparedStatement ps = con.prepareStatement(query); ResultSet rs = ps.executeQuery(); while (rs.next()) { Long id = rs.getLong(1); String comments = rs.getString(2); comments = comments.replaceAll(sourceRegularExpression, targetRegularExpression); PreparedStatement ps2= con.prepareStatement("update CustomerData set comments = ? where id = ?"); ps2.setString(1,comments); ps2.setLong(2,id); ps2.executeUpdate(); ps2.close(); } rs.close(); ps.close(); con.close();

Of course, all of the functions were called in a single large wrapper function. Thus the database was queried once for every string change. Every row that was retrieved was updated on the way back in. If the same row had multiple hits, it was returned and updated multiple times. Not to mention that the database would be grinding away as the number of customer comments grows over time.

Most importantly, Marcus can only hope that nobody ever commented about their first drinking and driving offense.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Representative Line: It's not the size that matters

Arrays are one of the most basic data structures. They’re a primitive in nearly every language. In languages like C, they’re low level structures, which represent direct access to memory.

Wally’s co-worker, Brandon, wrote an array declaration:

#define GRID_X 256 #define GRID_Y 256 #define GRID_ENTRY 1024 char stations[GRID_X][GRID_Y][GRID_ENTRY];

Multiply those together, and you’ll see a 3D array with 67,108,864 characters. That’s 64MB of memory, or 68MB if you manufacture HDDs. It’s a large chunk of memory to allocate all at once, and it’s probably a bad idea, but it’s not a WTF.

It depends on what the array is used for. In this case, it needs to hold some data from a simple database loaded from a flash drive. How much data is in that database? 10KB, which means this is roughly like trying to kill a flea with an asteroid the size of Texas, but that still isn’t a complete WTF.

Wally works in embedded systems. Their code targets a stripped-down Linux distro, running on a small and well understood piece of hardware. That piece of hardware has only 32MB of RAM .

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Error'd: Things Go Hilariously Wrong at Nuremberg

"The History Channel has a different interpretation of the events following the end of WWII than I was led to believe," writes Joe H.

 

I'm imagining that somewhere there's a guy out there running OS/2 Warp, teetering on the verge of finally switching over to Windows XP, but is holding back just because he still can print boarding passes from American Airlines' website. (Thanks Andrew!)

 

"Staples said there was a great value if I bought two, but I wasn't so sure," writes Allen Baldwin.

 

Scott J. wrote, "I have no idea how I did this, but something broke when I left my computer on overnight."

 

"We ordered a cake through the Dairy Queen website and wanted them to write our son's name in Russian," writes Alex A., "All looked good on the site, but then we got this."

 

"Apparently we first wrote this contract during the renaissance but lost it. Thanks for getting it back for us, Office 2013!" writes Chris Key.

 

"Deciding between hard or soft tacos was a tough choice," Jarad F. wrote, "Thank goodness Taco Bell made this desision easier."

 

"My Oracle screen timed out over lunch today," writes Andrew T., "Perhaps I haven't really been working as hard as I thought?"

 

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

CodeSOD: Coin Toss of Doom

The ticket at the top of Brian's queue seemed strange, but not entirely unheard of. A user had entered in a bit of data in a text box on the company's flagship internal web app, clicked Submit and - boom - immediately redirected to a 404 error page. The next ticket was for the same app, same page, same text box and data, but, to make things interesting, the user reached instead a Java exception page.

The rest of the tickets landing rapid-fire into Brian's inbox were more of the same...and using the user's input, Brian could reproduce both results at will. So. Much. Fun.

Undaunted, Brian dug into the code wondering what he might find. Was there some other process that was stomping on the application's memory? Perhaps there is a problem with the disk. (Was the server guy sick today?) The possibilities behind the root cause were nearly endless, the volume of which was filling Brian with despair, that is until he found the following.

Random r = new Random(); int flip = r.nextInt(3); if (flip % 2 == 0) { if (debuggingEnabled) { %>Redirecting...<br /><% out.flush();} // Handle redirects %><%@include file="/redirect.jsp"%><% return; } else { if (debuggingEnabled) { %>Declined<br /><% out.flush();} throw new Exception(Translate.translate(lang, "Declined.")); }

The code revealed that, upon error, users have roughly a 50/50 chance of being sent to a useless redirect page or getting an Exception thrown in their face. How could this is useful in any way? Was it some kind of sick joke!?

For an instant, Brian was tempted to flip a coin choosing to remove one error in favor of the other - OH SUCH POWER! - but in the end, he went for the more practical route. Brian applied an emergency fix to handle the user input and sent a note to his manager who was, ironically, the Machiavellian developer responsible for the code in the first place.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Testing Patience

The process used to test new applications before delivering them to the user base at Eric's company had never been particularly formal. This is not to say that there was no process at all. Of course there was. After all, what kind of a company would develop software and then release it to the user base without running it through some testing. But 'rigorous testing' and 'robust validation' were not phrases used within his organization. Neither was 'successful rollout' or 'satisfied users', but that's a story for another day.

One reason for the lack of formality was that the company didn't feel that having dedicated testing resources delivered sufficient benefit for the cost. Shouldn't developers just write code that didn't have any bugs? Was that so hard?

Still, it seemed prudent to someone at the company to have users test new applications prior to their release. So they assigned some people as testers. However, the testers only spent a portion of their day in that role. They also had other responsibilities that had to be performed in addition to testing. In Mark's case, that was customer support. Specifically front-line customer support. That guy that everyone either despised or tried to get around by asking for a supervisor.

Mark had been tasked with testing the new application that Eric had written. So it was not a surprise when Eric received a notice that a new bug had been logged into the tracking system by Mark. Since he was trying to meet a delivery date that was only a week away, Eric quickly read through the description.

Short Description: Paste not working Summary: I selected some text in Notepad. I went to the application and attempted to paste the text into a text box and nothing happened. And when I look at the Edit menu, the Paste option is greyed out.

Eric was slightly puzzled. But only slightly. It wouldn't be the first time that he had missed enabling the Paste button when the clipboard had content. Spinning up the application, he tried to follow the steps that Mark had listed. But to no avail. He couldn't seem to replicate the problem. Even a cursory examination of the code seemed to indicate that the Paste option should have been enabled. So he added a note to the bug and reassigned it to Mark.

I tried to replicate the problem you mentioned, but I had no luck. Is there something else you did that might provide a clue?

A couple of days later, the bug was reassigned back to Mark with the following addition

I may have forgotten a step when I created the bug originally. After I copied the text, I shut down the application. Does that help?

Now that's the kind of information that could be useful, thought Eric. Energized, he dove back into debugging. He tried shutting down Notepad. He shut down and restarted his application. He shut down Visual Studio. He even tried to shut down the local nuclear power station. And still that Paste option would light up. Even looking line-by-line at the code failed to turn up even a whiff of a cause. Frustrated, he added another note to the bug and assigned it back to Mark

Have tried a number of different combinations of shutting down applications and I still can't seem to replicate the problem. Is there anything else you can think of that you did?

It only took a couple of hours this time to get the bug back into his task list.

I'm afraid I might have forgotten one additional step the last time. After I shut down your application, I restarted the machine. Hope that helps. :)

Eric didn't move for about two minutes. A number of conflicting emotions coursed through his head. Rage at the company for not having competent testers. Pity for Mark because...well... Relief that a significant bug had been put to rest. As the emotions passed through him, they left only weariness. Slowly and deliberately Mark moved the mouse over to the Status combo box for the bug, opened up the options and selected "Closed - As Designed".

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

CodeSOD: The Apex of T-SQL

Thomas has some problems around the office. Specifically, the code he supports has all sorts of different ways to generate HTML. Rarely, it’s WebForms code living in as ASPX. Far more often, it’s hard-coded into the CodeBehind. Sometimes, it’s sitting in a resource file.

And then sometimes, it sits in a stored procedure like this:

ALTER Procedure [dbo].[proc_GetCurrentOrderStatus] @OrderId as Int,@MyVar varchar(2000),@LangId int, @Groupname varchar(10) As Declare @temp0 Table ( historyid int IDENTITY (1, 1) NOT NULL, historytext nvarchar(1000) ) Declare @temp1 Table ( errid int IDENTITY (1, 1) NOT NULL, errtext nvarchar(4000) ) Declare err_split Cursor for Select * from dbo.split(@MyVar,',') open err_split declare @langText as varchar(2000) Fetch Next From err_split into @langText While @@fetch_status=0 Begin insert into @temp1 values(@langText) Fetch Next From err_split into @langText End close err_split deallocate err_split

For those following along at home, this first block loads a series of language names from the clearly named @MyVar variable. With that cursor out of the way, we need to open a fresh one. It’s called History-cursor , and it’s populated from a basic SELECT statement. It’s after fetching the first record that things get interesting.

Fetch Next From History_cursor Into /* Snip */ @Lots, @Of, @Variables, @Here set @tablestr = '<table border = "0" class="texbox" cellspacing= "0" cellpadding = "5">' insert into @temp0 values(@tablestr)

Yes, that is hard-coded HTML dumped into a string variable and then dumped into a table variable. You’ll see a lot of that.

set @tablestr='' While @@FETCH_STATUS=0 Begin If @Groupname='Cust' Begin If @Status_Code = 'Cn' Begin set @tablestr = @tablestr + '<tr class = "textbox" >' set @tablestr = @tablestr + '<td nowrap ="nowrap" width = "250px" >Statut actuel de votre commande: </td>' set @tablestr = @tablestr + '<td nowrap ="nowrap" ><img src = ''' + @Status_Color + ''' width = "15px" height="15px" alt="album" />&nbsp; ' + (select errtext from @temp1 where errid=21) + ' </td>' set @tablestr = @tablestr + '</tr>' Break End

At this point, you might say, "Oh, I see how this works, this If repeats itself, almost identically, and the only variation is the errid used in the sub-query.

But no. Depending on the condition, you might see something like this:

If @Status_Code= 'Cn' Begin set @tablestr = @tablestr + '<tr class = "texbox" >' set @tablestr = @tablestr + '<td nowrap ="nowrap" width = "180px" >Statut actuel de votre commande: </td>' set @tablestr = @tablestr + '<td nowrap ="nowrap" ><img src = ''' + @Status_Color + ''' width = "15px" height="15px" alt="album" />&nbsp; ' + @status_name + ' ' + @Name + ' </td>' set @tablestr = @tablestr + '</tr>' End

Or perhaps, this:

If @VoucherID <> 0 And @Status_Code = 'N' Begin set @tablestr = @tablestr + '<tr class = "textbox">' set @tablestr = @tablestr + '<td nowrap ="nowrap" width = "180px" >Statut actuel de votre commande: </td>' set @tablestr = @tablestr + '<td nowrap ="nowrap" ><img src = ''' + @Status_Color + '''width = "15px" height="15px" alt="album" />&nbsp;' + @Status_Name + ' ' + @OrderNumber + ' ' + @Name + '</td>' set @tablestr = @tablestr + '</tr>' End

So similar, yet so different. This block is hundreds of lines long, and each condition does something subtly different from each other block.

Someone read that doing too much concatenation must be bad, so at the bottom of the loop, we have this simple step:

insert into @temp0 values(@tablestr) set @tablestr=''

After the loop closes and the cursors are deallocated, the rancid icing on this SQL-HTML cake:

set @tablestr = @tablestr + '</table>' insert into @temp0 values(@tablestr) set @tablestr='' Select * from @temp0 order by historyid

At least we can take solace in the fact that this is a small product from Thomas’s company. No one would build a large-scale product completely dedicated to generating HTML from database stored procedures, right?

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

The Six Million Dollar Patch

QA, UAT, and performance tests passed. John received authorization to promote his first major release to production. He checked in the code, and nothing exciting happened. No cake or streamers fell from the ceiling, but no errors or warnings bleated out at him. None. Given the complexity of the product, John’s success was the IT-world equivalent of winning both showcases on “The Price Is Right”.

John sent out emails to all the relevant stakeholders, and basked in the glow of a major project finally being done. The good feeling lasted for less than half an hour.

“The production servers are completely bogged down!” His boss clung to the threshold of his cube, breathless from the run over. “What the heck’s going on?”

Orders, orders everywhere. Tens of thousands of orders flooded into the production system. A glance at the log files explained their origins: the performance testing environment.

A horrible dread crept over John’s skin. “I must have left in some flags, or some settings- it’s pulling data from PerfTest. What should I do? Should I roll it back?” he asked.

“Yes, but get an OK from the system admin first,” his boss said.

His upcoming weekend, and potentially his career, were on the line. John emailed some attachments to the system admin on duty, then ran to the admin’s desk as though trying to beat the messages there.

The system admin had different ideas. “No need to roll the whole release back. Looks like all we need to tweak is this iBATIS query.” He tapped at his keyboard like a hacker in a bad movie. “See? Easy. Get this patch in before anything bad happens. Well, anything worse.

Weak with relief, John filed the emergency production change request with QA and release management. Once QA signed off, it would go into production without anything more from John. Everyone went home for the weekend, confident they’d done all they could.

To John’s surprise, the production-critical patch was still sitting in QA’s queue on Monday. And on Tuesday, Wednesday…

John didn’t need to inform the project lead. “I’ve been getting calls all week from people in Shipping. They’re sick of manually canceling those bad orders,” she said while popping several headache tablets. Her next action was to call the product’s main QA point of contact, placing him on speakerphone. “What’s the holdup?” she asked.

“We don’t have the financing to handle our workload,” the QA worker complained.

The project lead told her boss. John told his boss. They contacted the QA manager. Thus was the battle joined. The managers armed themselves with contact lists and SLAs. Conference calls and blamestorming sessions were the proving grounds over which these mid-tier titans clashed. With career interests and bottom lines dangling at the precipice, each vied to do as little as possible and spend the least amount of money while claiming the most credit. John’s urgent patch, a whopping eight-character code change, languished in limbo.

Nine months later, casualties stank up the battlefield. 1,000,000 bogus “orders” sent from the performance environment; $6,000,000 in losses for the company due to erroneous shipments, erroneously canceled real shipments, and angry customers. The only good thing was that by the time the damage was accounted, everyone had forgotten who released the bad code to production.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Error'd: Got Any Spare Error'd Change?

"It seems Wolfram|Alpha thinks that $13.02 should be paid with three coins," wrote Christopher.

 

Judging by the postage costs, Sandra Noronha's order is being shipped from the other side of the galaxy!

 

Alex writes, "All of these warning were really killing my performance, thanks to Final Cut Pro, now I can fix it!"

 

"Oh, my mistake I mistakenly entered my key for Norton AntiVirus when I should have entered in my key for Norton AntiVirus!" wrote Andrew T.

 

"Uh huh...sure, IE...not much risk here," wrote Steve Miller.

 

Jim S. wrote, "I guess it's not much use waiting around for the postman to get here."

 

"It sure is a good thing they tested downloads before finding out that routing was broken," noted Lee.

 

Dwayne wrote, "Nice to see Windows 8 is true to the Microsoft Tradition."

 

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

CodeSOD: Do Not Remove Complete!

It wasn't easy for Ben to find a snippet from the monstrous codebase he maintains that fully demonstrates the Whiskey-Tango-Foxtrot rating it deserves. Sure, there were calls to the data layer from the UI, and, yeah, there was at least one method called DoSomething() that no one dared to modify. But those are all de rigueur at The Daily WTF. He needed something... more. Something worse. Something layered, like an onion, and twice as eye-watering.

He needed this:

Application.DoEvents() 'If PrivateApplication.Globals.isInXXXXXMode And gstrAirlineCode = "XXX" Then ' Utils.WriteMsg("Loading Results...") 'End If ' NOTE: do NOT remove the word 'Complete' from the message below. ' It is used as a signal (to Utils.QStatusTimerProcess) to display the editor ' and hide the main screen and dialog box 'If PrivateApplication.Globals.isInXXXXXMode And gstrAirlineCode = "XXX" Then ' Utils.WriteMsg("Loading Results Complete. Please Wait...") 'End If 'JCXL: if XXXXX, notify XXX that the XXXXX optimization is complete ' *** NOTE: do NOT remove the word 'Complete' from the message below. ' It is used as a signal (to Utils.QStatusTimerProcess) to display the editor ' and hide the main screen and dialog box If gstrAirlineCode = "XXX" And Globals.isInXXXXXMode Then Utils.WriteMsg("XXXXX Optimization Complete.") End If

To enumerate, this code:

  1. Suspends UI redraw rather than use asynchronous UI and callbacks
  2. Uses a custom logging framework with no notion of log levels
  3. Is riddled with Hungarian Notation (not to mention the global variables it's used to indicate)
  4. Comments as a form of version control (what do you think the "C" in "CVS" stands for, Ben?)
  5. Best of all, passing control information via a poorly-named function that updates the text in a UI element. After all, why have separate signals for the program and for the user? Efficiency!

Don't worry, Ben: we won't remove the word "Complete" from "This is a Complete WTF", either.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

The Scottish Breakfast

There were days when Robert felt like a British Monarch. He worked for a cryptographic hardware/software company based in England, and spent his time bouncing from client-site to client-site, all across Europe. One day, a Scottish customer named Willie called, panicked because his cryptography server had stopped working. “Achh, I’ve givin er all I can give! She willnut run any more!” Robert settled Willie down and asked the obligatory troubleshooting questions (Is it plugged in? Is it switched on? Was the crypto hardware unit connected properly? Has a giant sea monster eaten your server?) but to no avail.

Robert then broke the news to Willie: this required on-site service, and Robert wouldn’t be available until the following week. “I’m actually in France today, at another customer site.”
“That willn’t do, laddy! I need this workin before I go to the Aberdeen football match on Sunday!” Robert informed Willie what the charges would be for an emergency weekend visit and Willie agreed without hesitation.

Robert boarded his Saturday red-eye flight. Willie laid out big bucks for him to fly first class. As he enjoyed his warm nuts and hot towel, Robert began to wonder what might be wrong with Willie’s crypto setup. It hadn’t been logging any errors and had been working fine until recently. The lack of any connectivity at all was confounding. It couldn’t be something simple, could it?

The plane landed and Robert checked in to his four-star hotel, but hadn’t time to sleep. He choked down the hotel’s “full breakfast”, which tasted more like haggis n’ eggs than the traditional, hearty meal he expected.

Robert pulled up to a drab, windowless warehouse in his rental saloon car. He nearly left, unsure if he found the right place, when Willie rushed out to greet him. “It’s ahbout time! Ah thought maybe ya’d fell in tha loch! C’mon in!” Willie led him through a dim hallway that opened up into a giant warehouse. The echoing space lay empty except for a sagging table, the server, and the cryptography hardware. “I’m payin ya for this, so ya better figger her out!” Willie threatened..

Robert gave the hardware a once-over and noticed the serial cable connecting the security dongle was loose. He tightened the thumb-screws, flipped the switch, and the crypto-server roared to life like a Scottish soccer hooligan after a red card. “Well, that was your problem…” Robert said without making eye contact with Willie.

“Mah god, that’s great, lad! Yoo fixed her!” Willie shouted as he gave Robert an uncomfortable bear hug. Robert bade Willie goodbye and headed back to merry England. On the flight home, Robert prepared the invoice to charge Willie for the trip expenses and a re-tightened serial connector. He couldn’t help but grin when the bill came out to several thousand pounds for about 5 minutes of work. Robert was happy, Willie was happy, the whole United Kingdom was happy.

[Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

CodeSOD: Nine Ways to Tuesday

Devan L. was playing with his young daughter, when she asked him if he knew all of the days of the week. He replied: Sunday, Monday, Frogday, Flubberday, ...

She quickly admonished him for being silly. He told her that he was a very busy man and that there were too many days to remember. They laughed.

Then he went to work and encountered the date utility library code below.

Now he wants to cry.

//This doesn't roll across month boundaries correctly //public Date getTuesdayInWeek(Date in) { // GregorianCalendar gc = new GregorianCalendar(); // gc.setTime(in); // gc.add(Calendar.DATE, Calendar.TUESDAY - gc.get(Calendar.DAY_OF_WEEK)); // return gc.getTime(); //} public Date getSundayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.SUNDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } public Date getMondayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.MONDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } // Not sure if this will work for leap years public Date getTuesdayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.TUESDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } public Date getWednesdayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.WEDNESDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } public Date getThursdayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.THURSDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } public Date getFridayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.FRIDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } public Date getSaturdayInWeek(Date in) { GregorianCalendar gc = new GregorianCalendar(); gc.setTime(in); return new Date(in.getTime() + (Calendar.SATURDAY - gc.get(Calendar.DAY_OF_WEEK))*24*3600*1000); } public Date getDateInWeek(Date in, int desiredDay) { switch (desiredDay) { case Calendar.SUNDAY: return getSundayInWeek(in); case Calendar.MONDAY: return getMondayInWeek(in); case Calendar.TUESDAY: return getTuesdayInWeek(in); case Calendar.WEDNESDAY: return getWednesdayInWeek(in); case Calendar.THURSDAY: return getThursdayInWeek(in); case Calendar.FRIDAY: return getFridayInWeek(in); case Calendar.SATURDAY: return getSaturdayInWeek(in);             default: throw new IllegalArgumentException("unknown desired day: "+desiredDay); } } public Date getReleaseDateInWeek(Date in) { return getDateInWeek(in, Calendar.TUESDAY); } [Advertisement] Make your team a DevOps team with BuildMaster. Pairing an easy-to-use web UI with a free base platform, BuildMaster gets you started in minutes. See how Allrecipes.com and others use BuildMaster to automate their software delivery.

Pages