But It’s Not MY Fault!

A few years ago I setup a calendar feed from Google Calendar to display my wife’s Zumba classes on her website. Sure Google has a bunch of iFrame and embed options but they’re ugly, and I wanted to make the list useful to participants so together, we came up with this:

given a class is today
and the class is at The Dance Shoppe
and the class start time is later than the current time
then display:
Today at The Dance Shoppe starting at 10AM

given todays class is cancelled
and the class start time is later than the current time
then display:
Today’s 9am class at The Dance Shoppe is canceled

given a class is tomorrow
then display:
Tomorrow at The Dance Shoppe starting at 10AM
Tomorrow at <where> starting at <starttime>

given today is Jan 1
and the next class is January 3
and the start time is 10am
then display
Jan 3 at The Dance Shoppe starting at 10am

given tomorrow’s class is canceled
and the class is at The Dance Shoppe
then display
tomorrow’s class at The Dance Shoppe is canceled

given today is Jan 1
and the next class date is jan 3
and the class is cancelled
then display
Jan 3 class at The Dance Shoppe is canceled

I found a Google Calendar jQuery library and implemented those scenarios. This would allow my wife to manage her schedule in Google Calendar instead of having to update HTML on her site.

I used Jasmine to build and test these customizations because I didn’t think it was really necessary to setup CI and run these tests before every change to the site as I was only updating the site every couple of months. The tests themselves are pretty simple. This one simply tested the function that checked to see if the class was today or tomorrow.

describe('display Today when the zumbaclass is today',function(){
it('will display Today if the zumbaclass is today',function(){

Not the most elegant solution but given I don’t update the site much, whenever I found a new scenario or found a problem, I had 7 tests in total I could run to make sure nothing broke. I stored them in a text file in my Webstorm project and I’d simply copy/paste the code and scripts into Jasmine, run them, make edits and then update my code.

Well today I discovered that the API’s this library was using are now defunct and a 403 message was being returned. Whoopsie.



A wise manager of mine had a simple way of dealing with problems. First, get the cow out of the ditch. Next, figure out how the cow got into the ditch. Finally, do something to prevent the cow from falling back into the ditch.

Rescue the Cow!

I commented out the script and restored a previous static calendar from Git and posted it.

Root Cause on the Cow!

Why was I using such a complicated solution to an easy problem?

  • I’m not a developer anymore so using pre-built libraries with minor customizations is something I can handle
  • My wife changes her class locations often so I was getting annoyed with having to update the site when the site was using a static calendar
  • My wife is not computer savvy so Google Calendar was the easiest option for her to manage her own calendar
  • I didn’t have any tests that covered error responses
  • I wasn’t running these tests nightly (or even monthly!) to find out sooner if something was broken
  • I wanted to practice BDD and TDD with Javascript!
  • I thought displaying class times and locations in friendly language was a better user experience than plopping in a big, crappy calendar

 Save the Future Cow!

There are plenty of options:

  • upgrade the library I’m using to Gcal’s V3 API (high effort…for me!)
  • go back to the static calendar (requires more effort long term for me, painful for my wife as I’m the bottleneck)
  • Plop in the ugly Google calendar
  • Find a new component to render her class list
  • Move to a CMS solution over a static site with a built in ‘event’ module (IE: Joomla or WordPress)
  • do nothing

There are more options, but I want to (eventually!) get to the point! There are 2 main learnings I took away. One about personal responsibility and one about the importance of craftsmanship.

The Responsibility Process

My first response was “damn you Google!“. My next response was “You stupid jQuery library“. After that I moved on to “If my wife could just do this herself I wouldn’t have had to fix this!!

Sounds a lot like BLAME!

Then I moved on to SHAME. “I knew this was going to happen eventually and I did nothing.” “If I wasn’t such a crappy developer I would have built a test for this scenario

I quickly skipped over Justify and Obligation and moved onto Responsibility. I’ll explore the options with my wife and find out what solution would work best for her.

I went through Christopher Avery’s Responsibility in a matter of seconds. Mostly because I was self-aware about going through the process. I knew I’d blame someone or some thing and then I’d blame myself, then I’d figure out a solution.

Knowing this, I simply waited until system 2 in my brain came back online and told my wife “Oh, bummer…give me a sec and I’ll fix it”.  My brain freaked out, but my mouth didn’t.

Craftsmanship Matters

I worked at a company that had a bunch of integrations to various social media sites and when these social media sites would change their API’s our stuff would break. The development manager always blamed the social media companies but never tried to do anything else to prevent the problem despite my attempts to “make him see the light”

Technically, this isn’t a hard problem to solve. If your application has a strong dependancy on stuff outside of your control (like 3rd party integrations), there are plenty of solutions. Develop tests that run nightly to validate the integration. It doesn’t have to validate everything, only the highest risk items. For mission-critical applications, this can happen during every check-in. It might be overkill in some cases but attention to detail matters.

Another solution is to use production monitoring to catch these problems in real-time. I could have a script running hourly in production to test response codes. If anything other than a 200 OK response happens, I can act. I can set a threshold that if a response code of 404, 403 or 500 happen I can retry X number of times and then default to a static calendar or link directly to the ugly google calendar.

The solution can be as elegant as it needs to be. Obviously given what I’m doing with this class calendar, I’m not going to spend a week building some over-the-top solution for a website that gets 40 – 50 unique visitors every day.

What I usually see happen is developers add error logging and some Ops person gets a daily summary email of a whole bunch of exceptions they have no idea how to handle. Eventually someone higher up finds the problem and yells at somebody and the cow is taken out of the ditch. Unfortunately no guard rails are put up to prevent the cow from falling back into the ditch.

This one seemingly small incident compounds over time and one day the organization wakes up and finds themselves technically bankrupt. Then they think Agile is going to swoop in and solve all these problems.

It won’t.

It’ll certainly magnify them, but it won’t solve them. How these problems are solved is up to the people doing the work. The only thing they need is to be empowered by management to do it.