Skip to main content

Error'd: I Believe In Lingonberries

3 days 2 hours ago

I've never been a huge fan of their furniture but I will happily demolish a plate of meatballs.

Jan agrees "My loyalty to this Swedish megastore is immeasurable."

"Choosing Concert Seats is Surprisingly Hard" for jeffphi who explains "While I have mixed feelings about indulging in nostalgia tours, I was curious to see seating options for this Rick Springfield concert. Turns out I *still* have questions!"

"Would you like to undo this unspecified problem?" richard H. rants "This came out of nowhere while composing an email. (I think I had just hit 'enter' to move to the next line.) Does anyone at Microsoft read these error dialogs before they ship it? Anyone? Is anyone at Microsoft forced to endure their own software?"

An anonymous fan of extinct charismatic megafauna complains "This is %{insult}"

Finally, and most seriously, merely pseudonymous WeaponizedFun has just highlighted for us that a true secret is something only one person knows. "Apparently, when OnSolve says "PROTECT YOUR USERNAME - NEVER give your username to anyone," this includes them not telling me what it is." See, if they told you, it wouldn't be a secret anymore.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!
Lyle Seaman

CodeSOD: Negative Days

4 days 2 hours ago

Killian Brendel was looking through the .NET source code, and found this comment on the TimeSpan struct.

// TimeSpan represents a duration of time. A TimeSpan can be negative // or positive. // // TimeSpan is internally represented as a number of milliseconds. While // this maps well into units of time such as hours and days, any // periods longer than that aren't representable in a nice fashion. // For instance, a month can be between 28 and 31 days, while a year // can contain 365 or 364 days. A decade can have between 1 and 3 leapyears, // depending on when you map the TimeSpan into the calendar. This is why // we do not provide Years() or Months().

Okay, a TimeSpan represents a duration of time. Makes sense. It can be negative or positive. Sure. It's a number of milliseconds. Okay, yeah. Other units of time get hard to represent that way, because months could have 28-31 days. Sure, yeah. I'm with you. And a year could contain 365 or 364 days, and a decade could have between 1 and 3 leapyears.

Wait, go back one. How long can a year be? I know negative leap seconds are going to be an issue, but negative leap days are gonna be way worse.

In the scheme of things, this isn't much more than a fat-finger typo. It doesn't impact the behavior of the class, which is why it's been sitting there since the initial commit, twelve years ago. The TimeSpan class itself hasn't been touched in that time, which also isn't much of a surprise, since it's really just a wrapper around a number of milliseconds. More complex date arithmetic, like AddMonths or AddYears is handled in the various date-time related objects.

So, is this a true WTF? Well, probably not. But it's interesting. Actually, the whole class is kind of interesting, as you can spot deprecated default constructors, as well as compile-time hooks for handling support for older versions of .NET including Silverlight, a technology that hasn't received an update since 2019, hasn't been supported in major browsers since 2015, and officially left support in 2021.

.comment { border: none; } [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
Remy Porter

Representative Line: Something Wonderful

5 days 2 hours ago

Today, we look at a "representative comment" from Mark W. This particular comment appears on a function:

/// <summary> /// Does something wonderful. /// </summary>

Well, I'm glad it's wonderful, but are we talking "Christmas magic" wonderful? Or sarcastically droll "Oh, how wonderful for you." wonderful? Tone doesn't get conveyed in text very well, so you've really got to be precise with your wording if you want us to get it.

Mark writes:

This comment is not really a 'representative' line; it exists in an otherwise very well written 100k+ line codebase.

Maybe it's not representative of the codebase as a whole, but it clearly represents this section of the codebase wonderfully.

.comment { border: none; } [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Remy Porter

CodeSOD: Convert Back, Way Back

6 days 2 hours ago

Windows Presentation Foundation, the XML-based UI framework for Windows, has its own "fun" quirks. One of its core ideas is that controls can be data-bound: that text box is linked to a numeric field in your model class. Type a different number, and the model automagically updates.

That's fine for what it is, but of course you're going to need to give it some instructions on how to do those kinds of conversions for your own custom types. And that's where the IValueConverter interface comes in.

You can write a class which implements that interface, which can then Convert and ConvertBack. Which, as a note, I hate that naming convention; which way is "back"? Well, that's controlled via an annotation. This is some of Microsoft's sample code, from their docs:

[ValueConversion(typeof(Color), typeof(SolidColorBrush))] public class ColorBrushConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Color color = (Color)value; return new SolidColorBrush(color); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } }

I don't particularly like this API, but again, it is what it is. This converts a color into a brush, and returns a null when we try and convert back, because that's not a valid operation.

Which brings us to Fredrika's submission. You see, there is a problem with this approach. If you bind a text box to a double? field, everything is fine and handled automatically- except the built-in converter doesn't turn empty strings into nulls. So one of her co-workers wrote this:

public class StringToDoubleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { double? parsed = value as double?; return parsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { string parsed = value as string; if (parsed == string.Empty) return null; return parsed; } }

Convert doesn't do anything. ConvertBack takes the string from our text box, checks if it's empty, and if it is, returns null.

Now, you'll notice something about the code here: when it Converts, it casts value as double? and when it ConvertBacks, it casts value as string. So that's where it's reaching out to the .NET Framework's built-in conversion functions.

I'm not entirely sure where to point to for the WTF, and some of that may be because I've had the good fortune to never have to use WPF. I don't like WPF's approach, but the developer behind this code isn't helping matters. Certainly naming variables parsed isn't clarifying matters.

I don't have a nice bow to put on this one. I just don't like any of this. I don't like the converter API. I don't like this implementation of it. I don't like trying to treat empty text boxes as null values, which I'm sure is correct here, but boy howdy do I suspect there'll be problems in the future.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
Remy Porter

The Hard Goodbye

1 week ago

One minute, you’re fine. The next, you’re doubled over with tears spilling down your face while an aching black hole in your heart threatens to drag you into oblivion.

Grief’s funny like that.

Aggie Shaw, my old friend and mentor, had died of a sudden illness at home. She’d lived alone. Who found her? How? I didn’t know and never would. There was so much I’d never gotten a chance to tell her. She would’ve listened to me vent the frustrations and resentments I’d been burying over the years for sanity’s sake. She would’ve known what to do.

God, I missed her.

As if that weren’t bad enough, the brass expected Tech Support to go right back to business as usual. Maybe the rest of them wanted to bury their heads in casework. I didn’t. Between this, the horrible winter commute, and the promotion I’d never asked for, going back to the office felt impossible.

My boss wouldn’t let me use sick time. He really should’ve; the grief had hit me like a goddamn truck. Good thing the start of the new year a while back had refreshed my stack of paid time off. I started burning it from both ends.

When I wasn’t flat on my back or nursing a migraine, I was stumbling around my tiny apartment with half a brain cell, attending to the bare minimum of survival. Eat this. Drink that. Where’d I leave my smokes? In the rare times I could think, my thoughts were plagued with darkness. I didn’t know if I’d ever make it out of that mess.

Then, Megan called.

It was nearing noon that day. I was lying in bed, peering out my window at a dull gray sky and falling snow. I’d let everything else dump to voicemail, but when she rang, I answered with the urgency of a drowning victim grabbing a buoy.

“Hey,” she greeted, her voice subdued. “I heard about what happened. I’m really sorry.”

There was so much tumbling through my head, but none of it wanted to tumble out. “Thanks,” I managed.

“How are you?”

“Lousy.”

“Wanna meet up somewhere that isn’t work?” she asked. “The Apex Tower has a big indoor courtyard. I eat lunch there sometimes. If we go around 10 in the morning, we’d probably have it to ourselves.”

Something in me leapt at the offer. “I’d like that. Tomorrow?” I would still be on vacation-in-name-only.

“Sure,” Megan replied. “See you then!”

I had something to look forward to. Part of my emotional burden lifted right then and there.

It was a little easier to get out of bed the next morning. I took the bus to an unfamiliar spot of downtown, crossed a slush-covered plaza, and entered a skyscraper. The warm ground-floor courtyard boasted marble floors and immense windows for walls. Potted trees and flowers lined the perimeter. Huh, I’d forgotten those even existed.

Megan was already seated at a metal table flanked by two chairs. When she spotted me, she jumped to her feet and waved, a knowing and sympathetic look on her face. She waited until I reached the chair across from her to say, “You look like you could use a hug.”

I froze with surprise, one hand on my hat in the process of removing it. A hug? My puzzled brain tried to figure out just when I’d been hugged last. I had no idea. My body wasn’t waiting around for an answer. It was already turning toward her, arms raised.

Megan silently walked into my embrace and hugged back firmly.

Tears spilled down my face. My heart ached. And yet, another part of my invisible burden suddenly lifted. Something in me had been dying for this, for my pain to be seen.

“Thanks,” I muttered.

We parted. While I doffed my coat and hat, Megan returned to her chair, sitting back down across from me. “Whatever you need to get off your chest, go for it,” she offered.

I sat myself down, sniffled, blotted my eyes on my sleeve, then glanced high and low to confirm something I already knew: we were alone in that big empty joint. Still, I hesitated. At first, I wasn’t even sure I remembered how to string words together to form a sentence. But then it started gushing out of me like a busted water main. “You ever hear of rubber-duck debugging?”

Megan blinked. “No.”

Surprising. Most developers had, but she was fresh out of college. “A programmer came up with it way-back-when,” I explained. “Whenever you’re coding something and get real stuck on a bug or error, you find yourself a rubber duck. Go line by line in your code and explain to the duck, out loud, what you want the code to do. Eventually, you and the duck will find the point where your intentions and reality don’t match up.”

She smiled. “I like that.”

“Aggie had a rubber duck in her cube she called RD,” I continued. “Whenever she was stuck with a support issue or even a personal problem, didn’t know where to go next, she’d tell RD about it. He’d help her figure out what to do or ask next.

“When I first got hired, Aggie showed me the ropes. She always said, the best way to troubleshoot is to be the duck yourself. Get people, or hardware, or software to explain what they’re trying to do. You’ll figure out how to proceed.

“Some people are so upset at the problem that they take it out on the nearest target: the support rep who comes to help. Aggie could charm even the angriest people into cooperating with her. She was the best. She was the best, and all she got for her trouble was more work. Now that she’s no longer of any use to them, they’ve swept her under the rug. They want me to replace her!”

Megan’s eyes went wide.

“I’m no damn manager! I told my boss where to stick it. I’m riding out my PTO, and then hell if I know what’s next. I can’t go back there, I’d just be dying in place. And for what? So the bum at the top of the food chain can have a third yacht?” I leaned toward Megan, my gaze pleading with hers. “Look, I ain’t afraid of death. I’m afraid of dying before I’ve lived. I don’t want my only contribution to the world to be reimaging laptops and rescuing old printers. I can’t do it anymore. Can’t sit around complaining, either, I gotta do something! I gotta get the hell outta that joint!”

There it was: out in the open again, no longer whispered but shouted from the core of my being. Leaving was the right call for me. I felt it in my bones.

Megan held eye contact, blinking a few times. “I remember you saying you wanted to leave. If you did, what would you do?”

I’d never really let myself play with my little pipe dream. “I dunno exactly. But I’ve bought myself time to think it over. There are options, like going freelance.”

She blinked again. “Freelance tech support?”

“I majored in Computer Science back in school,” I said.

Her eyes went wide again. “Really?”

“Haven’t flexed those muscles in a while, but I could. Or I could get into something totally different. And you could come with.” Well aware of how unhappy she was at that joint, I sat up straighter in my chair. “We could start our own IT group. No bosses. Everyone an equal partner with an equal say in how things are run. And we could rope in anyone else who wants to come with!”

Megan seemed intrigued at first, but then sobered. “What about bills? Rent? Everything?”

“We could pool our resources and look out for each other,” I said. “That’d give us some time to get our feet under us.”

Her expression turned strained. “Aren’t you scared?”

“You bet I’m scared!” I glanced down at the table. “When I first got outta school, the idea of spending the whole rest of my life at a full-time job terrified me. But it seemed like everyone around me was fine with it. I thought I was the problem. Bit my lip, put my head down … for 20 years.” I glanced back up at her pleadingly. “Has it gotten any better? No. I’ve just gotten used to it. Another 20 years, and I won’t be any good for anything else. That’s if I make it that long! Aggie didn’t. Look, there’s no right or wrong answer, just what’s right for you. Listen to your gut. If you don’t like where you’re at, I’m living proof that staying the course is the wrong move. Leaving is risky … but so’s staying put, you know. The next round of layoffs could be right around the corner. You might get stuck babysitting that scheduling algorithm you were telling me about.”

Megan listened intently to my rant. Finally, she nodded. “You’re right. I’m not happy where I am, and it won’t get any better. Time to try something different.”

Still mired in grief, I had at least gained a new sense of purpose to keep me afloat in the storm. Megan went back to work like nothing had happened. With my remaining time off from work, I did some research into our options. Hunting around online turned up a highly-rated accountant who walked me through the bare-minimum corporate setup, the taxes and bookkeeping and all that. We both tracked down advice online from other freelancers who’d been where we were now. And we put out feelers among our coworkers. Our questions struck some nerves, but also stirred considerable interest. Reynaldo was in; we had ourselves a network guy. Sanjay, a backend developer, was a maybe who wanted more time to think it over.

There were plenty who wanted to join us badly, but couldn’t swing it due to debt, insurance, things like that. I urged them to think about one thing they could improve at work, one cause they could get behind. Whatever it was, I told them to start making it happen, one step at a time.

As my PTO bled away, I found myself half-exhilarated, half-scared outta my wits.

Finally, it was time to go back. That first morning seemed like any other, but with my secret purpose in mind, I sat on the bus and walked the bone-chilling streets with a secret strength hardening my spine. When the old joint appeared ahead of me, more foe than friend, I felt relief knowing our remaining time together was short.

Tech Support seemed no different; everyone was quietly minding their own business. I’d had plenty of time to think about what I’d do on the first day. My plan involved skipping my cube and heading straight to Aggie’s old office. After my talk with Megan, I’d decided to go looking for something. I had a snowball’s chance in hell of finding it, but something in me insisted on trying.

As I walked up to the closed front door, the first thing I noticed was my name, not hers, standing out in fresh, gleaming gold letters against the frosted glass. Pushing past revulsion, I grasped the doorknob and turned it.

The door gave way to darkness. I flipped the light switch with my other hand and found an empty desk, gutted shelves, bare walls. Looked like someone had come through with a giant trash can and thrown out whatever wasn’t bolted down. My revulsion intensified, but hey, at least I wasn’t trespassing. I shut the door to “my” office behind me and slowly approached the desk.

There was nothing to be found out in the open, not even a stray paperclip. I sat down hard in her old chair, reeling for a minute. Then I searched the desk drawers in front of me: first the bank on the left, then the right. Empty. I pulled out the drawer just under the desk—and there he was, swimming between a few stray pencils: a rubber duck about 3 inches tall. RD in the flesh.

It was as if Aggie had put him there for me to find. I couldn’t believe it. My spirits soared in a way they hadn’t for ages.

Just as I slipped the duck into my trench coat pocket, the door to her—my—office swung open again, making me freeze. There stood Bill, my boss.

“I saw the lights on in here.” A smug smile spread over his face. “I knew you’d be back. Bet it feels great, knowing you’re done babysitting all those morons and their computer equipment!”

Was that it? Twenty-odd years of my life boiled down into one cynical statement? No, there was more to it than that. For every bizarre war story, there were tales of grateful people helped, challenging problems solved. It hadn't been all bad. But it was over, just not the way Bill thought.

An electric mix of nerves and resolve jolted me to my feet. “I told you to find someone else, and I meant it. This is my two-week notice.”

I left Bill agape in that threshold and hurried back to my old cube, where my company-assigned laptop, docking station, and phone still resided. I hung up my coat, sank into my old chair, and booted up the machine. I had such a mountain of email in my inbox that I didn’t even want to look at it, but there was one message at the top that I absolutely couldn’t pry my eyes away from:

I moved some things around on my calendar. 4:00 PM today is open. Please come to the executive floor.

-Leila


To be continued ...

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
Ellis Morning

Error'd: The Song that Never Ends?

1 week 3 days ago

"Watch to the end", the scammers demand. In today's episode of Error'd, the end is a long time coming. But at least it's amusing. In the meantime, Amazon irked and/or terrified thousands of their customers last week by mailing out ridiculously inflated bills. It's been covered extensively elsewhere but why should we miss all the fun?

It was Willy who worried "Amazon prices seem to have crept up this month, finance are going to have something to say"

Dave A. is on the horns of a dilemma. "Is it optional or required? Make up your mind, TAP! I'm TAPping my fingers waiting for you to decide."

"This rating is through the roof!" exclaims a regular who wants to be Anonymous today. "We're done with linear rating scales. Now you can have 5 stars on both X and Y axes. Also, given this is for a company that cleans roofs, we can make a joke this rating is out of the roof, and out of the <div> as well. In case you're interested and in case you want take a screenshot yourself: https://mijndakschoon.nl/" It's real; I checked.

Richard H. found a flubstituted email. "Quickbooks here reminding me that I failed to pay invoice number "{{rand_invoice}" Or this might be a scam/phishing email. Hard to tell." I'll bet {{money}} on scam.

B.J. H. is usually quite concise. Usually. "If this is ALL NORMAL I'm worried what will happen in an emergency"

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!
Lyle Seaman

Classic WTF: My Many Girlfriends

1 week 4 days ago
Honestly, with the wildfire smoke and the oppressive heat, maybe it's time to find a nice quiet cave to hang out in. Something with no natural light and no natural ventilation. I wonder if anybody has a place like that… Original. --Remy

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 me 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.

Thanks for the tip

Sten did not get hired at Initrode.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.
Remy Porter

Classic WTF: Server Room Fans and More Fun

1 week 5 days ago
It's been pretty hot lately. Probably should use a fan to cool off. Mind the trip hazards. Original. --Remy

"It's that time of year again," Robert Rossegger wrote, "you know, when the underpowered air conditioner just can't cope with the non-winter weather? Fortunately, we have a solution for that... and all we need to do is just keep an extra eye on people walking near the (completely ajar) server room door."

 

"For as long as anyone can remember," Mike E wrote, "the fax machine in one particular office was a bit spotty whenever it was wet out. After having the telco test the lines from the DMARC to the office, I replaced the hardware, looked for water leaks all along the run, and found precisely nothing. The telco disavowed all responsibility, so the best solution I could offer was to tell the users affected by this to look out the window and, if raining, go to another fax machine."

"One day, we had the telco out adding a T1 and they had the cap off of the vault where our cables come in to the building. Being curious by nature, I wandered over when nobody was around and wound up taking this picture. After emailing same to the district manager of the telco, suddenly we had the truck out for an extra day (accompanied by one very sullen technician) and the fax machine worked perfectly from then on."

 

"I found this when I came back in to work after some time off," writes Sam Nicholson, "that drive is actually earmarked for 'off-site backup'. Also, this is what passes for a server rack at this particular software company. Yes, it's made of wood."

 

"Some people use 'proper electrical wiring'," writes Mike, "others use 'extension cords'. We, on the other hand, apparently do this."

 

"I was staying at a hotel in Manhattan and somehow took a wrong turn and wound up in the stairwell," wrote Dan, "not only is all their equipment in a public place (without even a door), it's mostly hanging from cables in several places."

 

"I spotted this in China," writes Matt, "This poor switch was bolted to a column in the middle of some metal shop about 4m above ground. There were many more curious things, but I decided to keep a low profile and stop taking pictures."

 

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Alex Papadimoulis

CodeSOD: Classic WTF: Fork and Log

1 week 6 days ago
We keep our summer break going. Today, there's something floating in the pool, and I don't think it's a Snickers bar. Original. --Remy

A few years back, Adam C. was brought in to help with some performance problems that appeared while load testing a VXML Platform. The project was already well behind and they couldn't figure out why the system kept falling over under a very slight load. To make matters worse, Adam had absolutely no prior knowledge of the system or its software other than Wikipedia’s definition of what VXML is.

A veteran to these sorts of situations, Adam grabbed a coffee, a donut, and then started picking through the application logs to get a feel for what the system is doing and where something might be going wrong.

Looking in /var/log/messages, he was pleased to find with several days’ worth of messages, but over and over again, the same entry popped up:

Exception encountered writing error log.

"Seriously, who logs an error that they can't log an error? ...and is that even possible?" Adam wondered aloud after seeing the same senseless message for what he figured to be the hundredth time.

Frustrated, and hoping to learn what ludicrous conditions might precipitate a log to contain such a message, Adam dug into the source and hit paydirt in the form of this wonderful nugget of code:

public void error(String logID, String errStr) { StringBuffer errLogCmd = new StringBuffer("/usr/bin/logger -p "); try { Runtime rt = Runtime.getRuntime(); errLogCmd.append(errlogFacility); errLogCmd.append(" -t "); errLogCmd.append(logID); errLogCmd.append(" "); errLogCmd.append(errStr); rt.exec(errLogCmd.toString()); } catch (Exception ele) { System.out.println("Exception encountered writing error log." + ele.getMessage()); } } As he mentally parsed his way through the code, Adam could feel his breakfast tickling up from the back of his throat in reaction to the number of WTF’s he found himself facing.

He couldn’t decide what about the implementation was worse - forking off an external process to log something, the fact that log4j could have been used to send stuff to syslog (which the project used elsewhere), or that since the program's output was already piped to /usr/bin/log, just doing a System.out.println() would have been equivalent to this code.

As it turned out, this wasn’t the root cause behind the performance problems, but needless to say, that code got junked rather quickly and he moved on to looking for the next performance bottleneck.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!
Mark Bowytz

CodeSOD: Classic WTF: The Table Selector

2 weeks ago
It's summer break time, which as always, means we dip back into classic articles. Today, we pick which table we want. Original. --Remy

"In my native language of German," writes Christian, "the word quellcode is a pretty direct translation of 'source code'."

"Unfortunately, bad code seems to cross language barriers - as does that famous three-letter explicit adjective. But occasionally I’ll find a piece of quellcode that deserves its own special, localized expletive: quäl-kot. When I stumbled across this interface in our quellcode, quäl-kot was the first thing that came to my mind."

public interface ITableSelector { string selectTable1(); string selectTable2(); string selectTable3(); string selectTable4a(); string selectTable4b(); string selectTable5(); string selectTable6(); string selectTable7a(); string selectTable7b(); string selectTable8(); string selectTable9a(); string selectTable9b(); string selectTable10(); string selectTable11(); string selectTable12(); string selectTable13(); string selectTable14a(); string selectTable14b(); string selectTable14c(); string selectTable14d(); string selectTable15(); string selectTable16(); string selectTable17(); string selectTable18(); string selectTable19(); string selectTable20(); string selectTable21a(); string selectTable21b(); string selectTable22(); string selectTable23(); string selectTable24(); string selectTable25(); string selectTable26(); string selectTable27(); string selectTable28(); string selectTable29(); string selectTable30(); string selectTable31(); } [Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.
Alex Papadimoulis

Error'd: Princess Pricing

2 weeks 3 days ago

Sam suggests this Error'd indicates "Disney+ preparing the ground for usage-based billing." I'm intrigued by the idea that Disney might charge by the minute, but I suspect the reality is far more mundane.

Silly prices at online shopping sites don't usually make it through the gauntlet here, but I'm making an exception for the math, as Rob H. points out "it ain't mathin'."

and Harrison suggests a novel kind of discounting math "I went to the supermarket later at night for some beers, and had a snoop around the yellow sticker items for anything I might need or could freeze. This bakery item was priced in reverse, Was: 0.00, Now 1.99, discounted by negative infinity percent, and infinity is even printed upside down somehow."

We've got a mojibake from dragoncoder047: "Was browsing through the widget options on my iPhone home screen and found that Game Center had decided to do this. Mind you, my iPhone was, and always had been, set to English."

Finally a combination of typical time travel and package tracker shenanigans, not explained by time zone hijinks. Evelyn notes "Apparently the package was registered in July, on its way during January, and then got back to July."

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Lyle Seaman

CodeSOD: Wait Longer

2 weeks 4 days ago

Karen was maintaining some specification tests that were flaky. Not extremely flaky, but three or four times out of a thousand, the tests would just fail. The tests were complicated, and some of the operations were timing sensitive, so it wasn't precisely surprising- but the problem was that they were actually generous with their timing windows. The unit tests passed consistently, it was only these functional, specification-based tests that failed.

So, for example, there were sections in the tests where they wanted to wait at least 2ms. Since the code and tests were in TypeScript, they used the setTimeout function, which per standard JavaScript documentation warns that it may wait longer. But again, Karen was fine with longer.

Unfortunately for Karen, the documentation for NodeJS is less specific, as it makes no guarantees about when the timeout function gets invoked. This means that it can fire the timeout before the time has elapsed.

After many, many hours of debugging, that was exactly the situation that Karen found herself in. Which is why her very simple wait function went from:

export const wait = (ms:number) => new Promise((complete) => setTimeout(complete, ms));

To the much more awkward:

export const wait = (ms: number) { const target = performance.now() + ms; return new Promise((complete) => { const checkReady = () => { if (performance.now() > target) { complete(); } else { setTimeout(checkReady, 1); } } setTimeout(checkReady, 1); }); }

This version of the function checks the time every millisecond, and only completes the operation if we've waited at least as long as our target duration. This ensures that the timeout never fires too soon and it fixes the janky tests. But it's also terrible. Terrible that it exists. Terrible that this is the best solution. Terrible that our functional tests need to be so time sensitive. And terrible that the Node runtime actually breaks the one consistent scheduling guarantee that pretty much every other scheduler does: that it'll wait at least as long as you asked, but might wait much longer.

At best, we can say, "at least it's only testing code."

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.
Remy Porter

CodeSOD: The Error Check

2 weeks 5 days ago

Today's submission is less a WTF and more a, "Yeah, that'd annoy me too."

Stevie works in a code-base that's largely C, which means function return values are usually used to communicate to status codes. The standard:

BOOL success = someFunc(); if (!success) {// handle the error

If someFunc returns TRUE, we succeeded, otherwise we failed.

There's nothing wrong with that convention. But there is something wrong with one of the long-time developers on the project, because they have their own idiom for doing this. And they've been around long enough that their approach is the convention other developers follow. It's not wrong, per se, just confusing:

BOOL error = someFunc(); if (error == FALSE) { //handle the error errorCode = GetLastError(); //… }

Yes, pretty much anywhere an error can happen, they check if error == FALSE, and if that's true, they have an error.

I'd say, "at least they're consistent", but they're not. It's the convention, sure, but nobody wrote this down as the convention. New developers come in all the time, and they start out writing code in a more "normal" pattern. But the existing code has its pattern, and there is a lot of it. It has a mass and an inertia that is stronger than any developer. They don't change the code, the code changes them.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Remy Porter

CodeSOD: AAYFN

2 weeks 6 days ago

Jason M sends us some Ruby code.

def bv(prop, tv="Yes", fv="No", nv="Not Specified") v = self.send(prop) if v === true tv elsif v === false fv else nv end end

The obvious WTF here is the function name and parameter names. AAYFN(always abbreviate your function names) seems to be the convention here. But it also contains a more Ruby-specific WTF.

The function name bv is short for "boolean value", obviously. tv is the "true value", fv is the false value, and nv is the null value. So this is really about pretty-printing boolean values and converting them to strings. While the terrible names make it hard to understand, it's not that hard to figure out what's going wrong here. I hate it, don't get me wrong, but it just makes me sigh with disappointment, not groan.

No, the thing that makes me groan is v = self.send(prop). This is a very Ruby idiom that lets you access a member of the class by name; essentially it's like doing self.prop, but since prop is a variable containing a property name, we have to send it.

This is metaprogramming by strings, which is the main reason I end up hating it. But in this specific instance, it offers us a lot of potential issues. First, if prop is anything not boolean, we just return "Not Specified", which is incredibly misleading. I'd argue that if we attempt to use it on a non-boolean field we should throw an exception. Which opens the question: if prop doesn't exist, is that a non-boolean field, or is that a "enh, just call it null" situation? Because right now, that will throw an exception. It'll also throw an exception if the thing being accessed is a function that takes parameters. These behaviors may be surprising.

Now, I don't know the calling pattern. It's possible that whatever function calls this already has a good list of the allowed boolean values, and will never call this on a prop that doesn't exist. Certainly, that's what the Ruby docs recommend. But I'm going to hate it anyway, because this kind of runtime metaprogramming by passing strings around is eternally asking for trouble. And while I haven't done a huge amount of Ruby, I've done enough to know that any non-trivial codebase ends up like this once the metaprogramming band-aid is taken off.

Now, if you don't mind, I'll go back to doing my metaprogramming with C++ templates, which are simple, clear, and never result in wildly unmaintainable code because you ended up reimplementing LISP in template operations.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
Remy Porter

The Easy No

3 weeks ago

There were thousand tickets in the backlog, and I was on the trail of a weird printer issue. I had a suspect, but that wasn't enough to close the ticket. I'm Anonymous. This is my story.

Whenever you hit the Print button, a request launches into the ether. “Print one copy of this file, double-sided.”

But you can’t just chuck it out there aimlessly. You gotta tell it where to go. So that’s why we have Internet Protocol, or IP. Every computer, every printer, every device on every network has one or more IP addresses for different operations. They’re just like the address you scribble on the envelope holding Grandma’s Christmas card. Send your print request to the right IP, and you’re in business. Send it to the wrong IP, and they’ll be shaking their heads on the other end. “Print? But all I know how to do is tell you the weather!”

As for what happens next, you’re at the mercy of the program’s error handling. If you’re lucky, they’ll send a detailed error message. If you’re not, they could ignore you, act up in weird ways, or completely self-destruct in a violent crash.

I was neck-deep in a Tech Support ticket concerning a printer in Human Resources. Not only was Grandma’s Christmas card landing in Pluto, the Plutonians were writing back, in the form of mysterious complaints that were nothing like the documents the printer had been tasked with.

My troubleshooting hadn’t shot much trouble at all, so I’d bugged some friends for ideas. Reynaldo had been reminded of an old, retired HR program for logging anonymous employee complaints. While our developer friend Megan quit our icy outdoor break spot to dig up dirt from the software side of things, Reynaldo and I went to his cubicle to trace IPs. He suspected a conflict … and that’s just what his command-line requests revealed. We leaned over his laptop together, studying a couple of terminal windows and their cryptic output to his even-more-cryptic inputs.

“Whenever that printer got set up in HR, it received an IP that was already in use by this server—” he jabbed an index finger at the relevant part of the screen “—which is apparently still up and running, even though I swear it was decommissioned.” Reynaldo frowned. “Who wants to bet that stupid complaint program has some kind of ability to print cached complaints?”

I frowned, too. “We won’t know for sure unless Megan digs something up.”

Reynaldo flashed me a look of pure cynicism. It wasn’t an indictment of Megan’s skill, more skepticism toward the idea of anyone having properly documented this mess. We had better odds of hitting a billion-dollar jackpot.

I sighed. “It’s an easy workaround, at least: assign the printer a new IP. But we’ve got bigger problems here. Why’s this zombie server still up and kicking? Why’d an IP conflict ever occur in the first place?”

“Don’t get me started on our FUBAR IP allocation and tracking.” Reynaldo’s lowered voice contained plenty of venom. “We’re talking multiple pools to track, multiple spreadsheets that have to be manually edited. Problems that are easy enough to fix! Why spend money on honest-to-goodness network management software?”

Short-term budgeting preventing long-term improvements: a damned shame we’d both seen all too many times. Being a tech support drone, having an innate desire to help that no amount of baloney could stamp out, I once more found myself longing to fix the unfixable.

“In my ticket notes, I’ll make noise about a more permanent solution,” I said. “At the very least, some bigwig oughta leap at the chance to save 3 cents of electricity a year by putting the complaint-spewing server out of its misery.”

I’d already resolved to contact Leila, the new head of HR, about this ticket. She needed to hear about Hothead, the manager-type who, in a fit of frustration, had taken a hair dryer to the same printer and nearly trashed it. I could also tell her about these lingering network vulnerabilities that would continue causing problems for everyone down the line.

I decided to do it without telling Reynaldo. I had the feeling that if I let him in on it, his eyes would roll clear out of his skull.

Working from Reynaldo’s cube, I assigned the HR printer a new IP address and once again cleared its queue. Then I sent Tony, the ticket holder, a private message asking him to give printing another go. I felt pretty good about his chances, but I’d wait for him to give me the all-clear before closing the ticket.

With the messaging app still open on my phone, I saw that Megan had invited me to drop by her cube. From Networking Central, I hoofed it up to Developers’ Row.

Megan’s cube was a familiar spot filled with bright, cartoony posters and figurines, the only splashes of color for miles. The titles and characters drew blanks in my over-the-hill brain. I kept meaning to ask her what they were, why she liked them. Another time, maybe. I found her with her back toward me, leaning intently in her swivel-chair toward the single monitor over her laptop docking station.

“Now a good time?” I asked under my breath.

She whirled around, tense, then relaxed with a smile, her gaze livelier than I’d seen it in a while. She picked up a small external memory stick from her desk to proffer my way. “That’s the HR application’s source code!” she murmured in conspiratorial fashion. “Guess where it came from?”

I smirked. “I know the answer should be ‘a code repository,’ but in this joint, that’s asking too much.”

“You’re right!” she replied. “It was never in a repo, never in source control. It lived and died on one dev’s local machine, a dev who retired way before I got here. His successor hung onto all the old code from that guy’s machine, just in case. But yeah, we don’t officially support the application anymore.”

Megan turned around, using her keyboard to tab over to an open window in a code editor. From over her shoulder, I saw line after line of an archaic programming language that the Egyptians might’ve used to build the pyramids.

“This code’s an undocumented disaster,” she said.

“There was an IP conflict at that,” I told her. “The print requests were going to a server that’s still running this thing. We assigned the printer a new IP, but the mystery server remains a head-scratcher.”

“I’ll trace through and figure out what it does when it gets a print request. Improve its error-handling in general,” Megan promised, more excited than daunted by the prospect. “I mean, if it is still up and running, I could tweak, recompile, and redeploy it so it doesn’t—”

Insistent metallic knocks sounded behind us. “Excuse me!”

It was the sort of pointed voice that somehow ignored your ears and stabbed into your gut instead. Megan froze, tense. I turned to find a woman at the threshold with the bearing of a vindictive hall monitor, rapping a fist against the cube’s bare metal frame.

She leveled a withering frown at Megan. “I was hoping for a status update on the Hewville refresh! Did I hear you say you were planning to work on something else?” The question sounded more like a threat.

This had to be Megan’s boss. Megan remained tense from head to foot. “I—”

“I need you to focus on your assigned projects. The things you can actually bill your time against.” After delivering the condescending reminder, the boss’ glare shifted my way. “And you are?”

I shoved unease aside and put on the game face I’d spent decades perfecting. “Tech Support. I meant no harm, ma’am. I was just asking Megan for help with an open support ticket.”

“She doesn’t have time for that!” the boss scolded. “If you truly need help from this department, then you must escalate your ticket through the proper channels.”

I already knew how that went: pulling together screenshots, logs, and other detailed information, only to receive half of a sentence fragment a few days later, asking for something I’d sent with the first message. In this case, I knew someone would just wag a finger at me about the HR application being out of support. Thanks but no thanks.

Megan struggled to muster one last defense. “This program’s still running on a server somewhere!”

“For changes to existing code, the proper procedure is to file a formal change request through the Project Management Team. The PMT will create a billing code and assign appropriate resources, if they deem it a proper use of development time.” The boss then looked at me like I was a used tissue she was ready to throw in the trash. “If that’s all, I suggest you head back to Tech Support, Mr. … ?”

No way was I handing her my name on a platter. I tried to glance Megan’s way, but she was staring at her lap. I felt bad leaving her in that lurch, but staying would only make things worse for the both of us.

“Later,” I said, both a goodbye and a promise.

I got the hell out of Devsville, slipping down flight after flight of stairs with a lead weight in my chest. For a moment, Megan had brightened in the face of a collaborative challenge. I’d felt a little more alive, too.

Thank God someone had been there to make sure no one helped each other.

The same sicknesses plagued the joint year after year. Almighty budgets. Status quo worship. Hierarchy and miles of red tape. Promising young people like Megan had their spirits crushed, and schmucks like me just put their heads down. Still a huge pile of other support tickets waiting for me, after all.

The frustration and resentment, the desire to do something to fix this, burned in my chest like a bonfire.

Back at my desk, I found a message from Tony confirming the new printer was behaving at last. Bolstered by my friends’ findings, I closed his ticket with notes about how the resolution was only a band-aid on a gaping wound. I messaged Megan, too, thanking her for trying.

And with that emotional bonfire still raging, I settled in and typed out a long email to Leila, detailing in full the most recent shenanigans I’d been a part of.

By the time I finished, I had one bit of good news: Aggie, my old mentor who’d turned manager a few years back, had accepted my meeting request to meet the next afternoon.

She wasn’t my boss, which meant it was still safe to vent her way. I had every intention. My resentment would no longer let itself be buried under this or that technical hiccup. It was insisting upon action.

The next day, I walked to the downtown coffee shop well ahead of the appointed time, glad to have the excuse to be somewhere else. Bought myself a drink and sat down where I could watch the door.

Five minutes late turned into ten … then twenty. No Aggie.

It was totally unlike her. Sure, she’d canceled last-minute before, but she’d always got in touch with me to let me know.

Caffeine jitters fueled a fear I couldn’t shake off. I sent PMs and left voicemails on her cell and work phones, asking her to respond when she could. Back at work, I asked around the department, including my boss.

She’d been AWOL the whole day. No one knew what was up.

Hours of work still stretched in front of me. I could barely sit in my chair, much less look at my monitor.

Just call me, Aggie, I willed, staring at the cell phone clutched in my hand.

She didn’t. Not that afternoon, not that evening. Beneath my fear was this strange gut feeling, this knowing sense that my worries were justified. It was crazy, but there was no talking myself out of it.

Early the next morning, they roped the whole department into the big conference room. Nobody knew what was going on until a small, ashen group of managers, directors, and directors of directors filed to the front and called for attention.

I already knew, deep down, what was coming.

“We’ve we received some very unfortunate news,” one of the senior directors spoke. “Agatha Shaw … passed away in her home after a heart attack.”

A few gasps escaped the assembly. Otherwise, you could’ve heard a pin drop. Wide-eyed looks of shock surged through us like lightning.

Aggie.

My gut had known all along, but my brain still wasn’t having it. Somebody somewhere must have goofed up royal, I thought. Happens all the time in this joint. Aggie had more life and fight in her than I ever did. I—

“Those of you who reported directly to Ms. Shaw will report to Bill Watson for now,” the director continued. “Dismissed.”

The brass began showing themselves out.

The rest of us just sat there, too stunned to move. That’s it? I marveled. No memorial? No counseling? No time off? Not one drip of sympathy?

I could only look on helplessly as Bill Watson, my boss, walked right over to me. He put his hand on my shoulder, leaned over, and muttered into my ear: “My office.”

While my brain reeled, my feet stood me up obediently. They marched me right off to the next chair I dropped into, the one opposite the large desk in Bill’s office.

He settled in on his side. “It’s a real shame about Aggie. We’re screwed without her.”

I just sat there, still reeling.

”My manager is looking for someone to step up in a big way.” Bill nodded in my direction. “You’re ready. You deserve it. Her direct reports are reporting to me for now; over the next few months, I’m transitioning them to you. The promotion will follow, as soon as the next performance review comes around!”

We were just cogs in that joint. Never before had the point been driven home so viscerally. Righteous rage surged up from within, clearing my brain and shooting strength through my limbs. I jumped out of that chair and glared down at him. “Hell no! Find someone else!”

I got the hell out of there and dragged myself all the way home to collapse on my couch.


To be continued ...

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
Ellis Morning

Error'd: Einfach so

3 weeks 3 days ago

Do you say "a FAQ" or "an eff eh cue"? Peter says eff eh cue I think.

"This is a test" Peter G. harrumphed testily. "Create an FAQ with exactly nine entries. Nine? Nine."

"I think I spent over $NaN?" said an anonymous. "This was an interesting offer on myminifactory.com with tight expiry date. Didn't claim."

And a different reader expected a speedy delivery anon. "It was about 23:10 UTC when I took this screenshot, the time zone I keep my PC in, yet local time my pizza was estimated to arrive at 19:05 CST. Naturally, I should expect to receive my pizza about four hours ago! Not my typical experience with delivery as of late, I must say, but a welcome change nonetheless..."

Super saver Michael R. lamented "That hurts, I missed 6 coupons that would have saved me 0%."

And our dragoncoder047 ground this out between his teeth. "Refactored the runtime spritesheet packer in a game engine I contribute to, and wound up with this extremely helpful error message. Turns out that the problem was the ggggggggggggggg wasn't properly detecting ggggggggg and was putting all the ggggggggggggg's in the same ggggggggggggggggggg. I think. Ggggggggggggg!"

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
Lyle Seaman

Flushed Out

3 weeks 4 days ago

While a project manager is frequently called upon for their planning ability, the real skill we want from project managers is their ability to communicate. The job of a project manager is to align the team doing the work, with the organization goals driving the work, with the management and leadership teams trying to understand the work, while juggling all the constraints like budgets, timelines, and the endlessly changing expectations for the project. A good project manager is worth their weight in gold. A bad one will cost their weight in gold.

Mark was hired on as a contractor, reporting to Tegan. Tegan was fresh out of business school, complete with an MBA and a variety of project-management training certifications. Unfortunately for Mark and the rest of the team, and especially unfortunately for Tegan, she had absolutely no real world experience. To make matters worse, this wasn't just a software project: they were working on a system which matched newly developed software with newly designed mechanics and custom build control electronics. A group of experienced software engineers, mechanical engineers, and electrical engineers all found themselves reporting to a bright and shiny MBA. It's a role that she probably could have grown into, but management saw all the acronyms she continuously put after her name, and decided she could just take the whole thing over with no real guidance.

It went badly pretty much from the beginning. Tegan was not a talented communicator. For example, Mark's team needed to know: on what timeline were the electrical engineers going to deliver the first prototypes, so the software team could start running bench tests of their software? Tegan's response was a fortune cookie message about balancing the complicated pipelines and lanes on the Gantt chart and hitting all of their milestones; like a fortune cookie, it was vague, important sounding, but ultimately empty.

Of course, the natural reaction amongst the engineers was to just route around the damage: the various teams could talk to each other just fine without going through Tegan. That, unfortunately, did not go over well with management. Tegan, as the project manager, was their insight into the project. They needed her in the loop on everything. And she couldn't just be informed, she had an MBA. She needed to be making decisions. But she was unqualified to make those decisions, which meant the project gradually ground to a halt. Tegan's emails got more vague, her meetings got longer but accomplished less, and after a certain point, she just stopped replying to key email threads.

The first few days of radio silence seemed like a gift. But as time passed and Tegan seemed uninterested or unable to reply to any of the questions the team had for her, the project started to flounder. The engineering teams escalated this problem to management. Management presumably went back to Tegan. At some point, feeling the weight of everything going wrong around her, Tegan sent out this email, which is definitely the best and clearest communication she managed during the project. It's arguably the clearest, and most accurate communication one could make in this situation:

Team,
I understand all the issues but there are complex interrelations that must be worked out. I am currently constipated on each issue and will let you know when there is movement.

  • Tegan
    MBA, CAPM, PMP

Her email cost the project many person-hours as all the engineering teams took a break to have a good laugh about the project manager admitting, in writing, that she was full of crap.

There was, eventually, movement. Tegan moved on to a new position at a different company. Her replacement, Pam, wasn't a new hire, but instead a transfer from another department. She wasn't a great project manager, certainly not worth her weight in gold, but she had enough experience to avoid the worst mistakes, and most important: she was good at regular communication in order to keep things moving.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Remy Porter

CodeSOD: Module Test

3 weeks 5 days ago

TJ inherited a NestJS project. The original developers left the team many years ago, but they've left their mark in the codebase.

// ProjectsModule.ts @Module({ controllers: […], providers: […], exports: […], }) export class ProjectsModule {}

NestJS is a dependency-injection oriented framework for TypeScript code. It offers "providers" (dependencies that can be injected), "controllers" (as one would expect), and lets you bundle them together into "modules". Modules can depend on other modules, letting you build a modular and flexible graph of dependencies. This means that the empty module isn't wrong here.

No, for it to be wrong, we need to write some tests:

// ProjectsModule.test.ts describe("ProjectsModule", () => { it("can be created", () => { const projectsModule = new ProjectsModule() expect(projectsModule).toBeTruthy() }) })

Since modules are just containers for related code objects, there isn't much to test here. While "dynamic modules" which execute code are a thing, they don't execute that code at construction time anyway. This test will always pass. It isn't a test, it doesn't do anything. It likely doesn't even get their coverage up, since whatever providers or controllers it's referencing aren't covered by this test. It's a test that tests nothing but the framework it runs on top of.

"At least there are tests," TJ writes.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.
Remy Porter

CodeSOD: On Hold

3 weeks 6 days ago

"Dragoncoder" supports a web application that has a "wait time" for access. I hate that that's a thing, but I recognize that there are real-world constraints where this might make sense. Still, I hate it. But that's not the WTF.

var minutes = parseInt( 12 , 10); var time = document.getElementById('waitTime'); if ( minutes < 2) { time.innerText = "Your estimated wait time is 12 minute." } else if (minutes < 60) { time.innerText = "Your estimated wait time is 12 minutes." } else if (minutes === 60) { time.innerText = "Your estimated wait time is 0 hour." } else if (minutes < 120 && (minutes % 60 === 1)) { time.innerText = "Your estimated wait time is 0 hour and 12 minute." } else if (minutes < 120) { time.innerText = "Your estimated wait time is 0 hour and 12 minutes." } else if (minutes > (60 * 4)) { time.innerText = "Your estimated wait time is more than 4 hours." } else if (minutes % 60 === 0) { time.innerText = "Your estimated wait time is 0 hours." } else { time.innerText = "Your estimated wait time is 0 hours and 12 minutes." }

This wait time page is initially rendered by their backend, but after that point, gets served up by a cache at the edge of their CDN. That makes sense, since "have the users hammer your backend while they're waiting" is a bad idea.

Note the line var minutes = parseInt( 12 , 10);. This is rendered from the backend, which is of course my least favorite way to send data from the server side to the client side.

But that's not the core problem here. The core problem is: what the hell are they outputting?

If your wait time is less than 2, or less than 60, we tell you that your wait time is 12 minutes. Or "12 minute", because who cares about pluralization? If your wait time is exactly 60 minutes, we tell you that your wait time is "0 hour", which I assume means you'll have enough time to watch the classic airplane disaster movie, Zero Hour, which you surely know Airplane! is a remake of.

I can only think that the text is also being generated by logic on the server side- though our submitter doesn't suggest that's the case. Though they do wonder why the code couldn't be something like: Your estimated wait time is: ${Math.floor(wait_time_minutes / 60)} hours and ${wait_time_minutes % 60} minutes, which is both fewer bytes to send from your cache and more useful to the end user.

Or maybe we just make this wait time go away. Again, I don't know why it's there, there may be a good real-world constraint that requires it, but… is there? Is there really?

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
Remy Porter

Best of…: Classic WTF: Difficult Personality

4 weeks ago
As the US took this weekend to celebrate their complicated relationship with tyranny, we reach back through the archives for another story of tyrants. If you think about it, the Declaration of Independence is basically the same thing as quitting without notice. Original --Remy

It was Steve's first week on the job, and he had plenty of questions about the code base and the new features he was supposed to implement. He muddled through for most of the week, but Friday morning he hit a brick wall and needed to talk to Bill, the architect.

"Can I meet with you for like an hour to go over things?" Steve asked.

"No."

"Can I get half an hour then? I h-"

"No. Company meeting, every Friday, 12-5pm. It should be on your calendar. I'll forward the invite."

Bill also couldn't free up time in the morning, so that meant Steve was stuck until Monday afternoon. Still, it probably wasn't all bad. He assumed that since this was a small company, in startup mode, it was going to be one of those meetings that was less meeting and more party. He had heard about one company in town that had a kegger every Friday afternoon.

Steve really should have known better. During his interview, the actual technical questions were thin on the ground. It focused more on "soft skills", like time management. He fielded a lot of questions about how best to manage his time. The other question that really stuck out in his mind was the standard, "Have you ever had to deal with a difficult personality in the workplace? How did you deal with it?" It was memorable, less because the question itself was unusual, but because at least six variations of the same question showed up in the interview.

On his very first day, he learned who the difficult personality was: Frank, the boss and grand-high pooba of the dev team. Around 2PM Frank lumberghed himself into Steve's cube. "Yeah, we've got a little problem," Frank said. "I've noticed you spending a great deal of time in the break room."

"Oh, yeah, I was just going back for more coffee," Steve said with an awkward laugh. "You know how it is with programmers- we're fueled by caffeine."

"Yeah, well, if you could just go ahead and make sure you're at your desk doing work, that would be great."

As it turned out, Frank had gone easy on Steve because it was Steve's first day. The next day, Steve sat in on Bill's planning meeting- a 4-hour marathon to organize the development backlog and parcel out work. Halfway through, Bill called for a break. He and a few other co-workers darted outside to gradually commit suicide via cancer, while everybody else hung around the room committing suicide by donut. And then Frank walked in.

"What's happening?"

"It's um… just a little break," one of the devs replied. "Bill's outside."

"I see." Frank loitered in the room until Bill returned. The instant Bill's foot crossed the threshold of the meeting room, Frank's human facade was stripped away, and a spitting, slavering demon replaced him. He proceeded to dress Bill down, back up and right back down for disrespecting his team, disrespecting the company, disrespecting Frank and Frank's poor elderly mother with his attitude. He closed with, "They're developers and I want them sitting around and developing! Not waiting for you to finish your smoke breaks!"

On Thursday, Steve got to drive a meeting to show off the latest batch of features the dev team had completed. When he turned on the projector, Frank asked, "What's wrong with your computer?"

"Um… nothing?"

"The desktop is wrong! None of the icons are in the right place!"

Like most developers, Steve had changed the wallpaper and reorganized his desktop to suit his working style. Unfortunately, his transgression against the default desktop settings set Frank off on a long rant that consumed the entirety of the meeting. Steve was lucky, Frank claimed, that he wasn't fired on the spot. Standard work was vitally important, and personalization was frowned upon. "It's vitally important that any developer can use any other developer's computer- we can't afford to waste a minute of time just because you needed to be a special little snowflake!"

By the time the Friday afternoon meeting rolled around, Steve should have been expecting some kind of Frank-led time management course. Instead, Bill handed him a mop. "New blood gets mop duties. Start in the break room, and then hit the other common areas."

"Excuse me?"

"Frank's orders. Every Friday, we spend the afternoon cleaning the office, from top to bottom."

"There isn't a cleaning crew?"

"Oh, there is," Bill said. "Frank doesn't trust them to do a good job." That weekend, Steve decided to take Frank's lessons on time management to heart, and immediately left to seek employment that didn't involve wasting his time.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Remy Porter
Checked
1 hour 47 minutes ago
Curious Perversions in Information Technology
Subscribe to The Daily WTF feed