Delta nightmare

I normally post only technical stuff on the blog but I had to rant about this nightmare on Delta that I had last night.

I was flying DL1152 from Honolulu(boarded on Oct 15th) to San Francisco with my wife and I had my worst flight experience ever right from getting my boarding pass to checking in to the flight. I had booked this flight at least 3 months in advance and our seats were not together. While getting my boarding passes at the gate, I checked with the ticket agent if she could put us together. She said that she has put my request down and will be calling my name soon. She never called our name, and every 20 minutes or so, when I would go to the counter and ask about the seats, she would reply: "I am working on it and I will call your name". In the meanwhile she kept on allotting seats to standbys and upgrading people. Then came the final announcement to board the flight. I rush to the ticket counter and ask the ticket agent, if she managed to get us a seat together and she replies, "Sorry sir, the flight is full and we cannot put you together". We were the last person to board the flight. I would have appreciated if she could have called my name and let me know that she won't be able to accommodate my request rather than me asking her all the time. Moreover, I don't know what Delta's policy is but I did see the agent accommodating requests from other people who were either standby's or checked in at the counter much later than I did.

Well, this was just the start of my nightmare. What ensued later, was the worst display of customer experience that I have ever heard of. I had two conversations with  two of  Delta's air hostesses.

1st conversation

I was walking down the aisle to my seat with my carry on baggage and was stopped midway by this hostess.

Hostess: I wonder how did the guys upfront allow you to bring your bag till here. The flight is full and there is no space in the overhead baggage cabin. You will have to check-in your bag.

Me: I have some fragile glass stuff in my bag. I am sorry I cannot check it in. Can you please help me find some space?

Hostess [continues to smile as if she did not hear/care what I said]: Sir, there is no space. You will have to check it in.

Me: Its not my fault that there is no space. I was held up by Delta's ticket agent for no reason and thats why I am the last one to board.

Hostess[keeps smiling and repeats] : Sir, you will have to check it in.

Me:  Ok, I will check it in but if something breaks, will you or Delta pay for it ?

Hostess[ keeps smiling ] : Sir in that case, I will have to put you in a different flight.

Me: I have booked my seat on this flight 3 months ago and I don't understand why you would suggest me to get a different flight when you overbooked the flight. I have two tickets and I don't get a single spot to put my bag in overhead cabin. If you cannot help me, let me walk down to my seat and see if I can figure out something.

2nd conversation

Now I walk down to my seat and put my bag under my seat. There was a very helpful couple sitting right next to me. They said that they have a bag that they could check in and that would allow me to put my bag in the carry on baggage. This is the conversation that me, the helpful co-traveller and the hostess had.

Co-traveller [ to the hostess ] : I have a bag that I can check in. Can you please check my bag in ?

Hostess[to the co-traveller]: Sorry no more check in bags. Also you don't have to worry, its not your problem.

Co-traveller [ to the hostess ] : Let me see if I can put my bag below the seat in front me. Then he can put his bag in the overhead cabin and sit a little comfortably.facebook

[ The co-traveller stands up, opens the cabin and tries to move her stuff. Hostess stops her ]

Hostess [ to the co-traveller]: You don't have to worry. Its his problem, let him figure out.

Hostess [ to me ]: There is a little space in the cabin, do you think you can fit your bag in there .

Me [ completely startled at this behavior ] : I am sorry but there is literally no space there for my bag to fit. Even you can see that.

[ In the meantime, my co-traveller just stands up and moves her bag to the seat in front of me. And then I put my bag in ]

All through the two conversations that I had with two different air hostesses, they cared the least about my comfort or the safety of my stuff. It totally pissed me off to see that even when my co-traveller was ready to help me, she was trying hard to make sure that it did not happen and I checked in my bag.

I always thought that Delta has one of the better customer experiences but yesterday's horror has disappointed me to such an extent that I dont think I will be flying Delta again.

Bookmark and Share

Leave a Comment

Browser and NodeJS

I am writing a new javascript library and I wanted the library to work server side ( nodejs ) and in the browser. The main question that I had was how to design my code so that I can use the same files both with node and in the browser. I had a file called base.js which needed some utility functions from util.js .And I wanted my code to work in both the browser and with node.

Here is what my base.js looked like:


(function(global) {
var $b = global;
var $u = ( typeof exports !== "undefined" ) ? require('./utils.js').Utils : global.Utils;

......

})(typeof exports !== "undefined" ? exports : window );

This compiles fine in node. and then in the html I include utils.js above base.js and things work fine there too :)

Bookmark and Share

Leave a Comment

Greasemonkey and avoiding the sandbox

Recently, I was trying to write a greasemonkey script to override the HTMLHeadElement.appendChild function in the browser DOM. Well, the reason I was trying to do that was to redirect a json-p call to my servers instead of the once mentioned in the webpage. Json-p works by dynamically adding a script tag to get around the cross-domain restriction policy of browsers. So, in most cases the script tag is added to the "" element. What I was trying to do was :


HTMLHeadElement.prototype._appendChild = HTMLHeadElement.prototype.appendChild;

HTMLHeadElement.prototype.appendChild = function(node) {
if(node.nodeName == "SCRIPT") {
var new_src = "http://foo.com/?...";
node.setAttribute("src", new_src);
}
HTMLHeadElement.prototype._appendChild.apply(this,arguments);
}

Well, this script worked on the Firefox console. But, it turns out it does not work as a Greasemonkey script. The reason being the greasemonkey scripts are run as part of a sandbox, and so do not have access to all the window elements. ( I wonder why ? ) . I even tried using "unsafewindow" , but even that does not work. You get access to HTMLHeadElement, but HTMLHeadElement.prototype is undefined. So, what now ?

Well, there is a simple workaround. Just modify your greasemonkey script to run the above code as part of the script in page. Basically, create a script tag, and add the abpve script as part of the script. Now since, this code will run in the context of the page and not in the context of the greasemonkey script, you will not have to worry about any restrictions imposed by the greaemonkey script. I basically put all my code in a separate js file and then loaded that into the script tag using greasemonkey:

var scriptElement = document.createElement("script");

scriptElement.setAttribute("src", "new_js.js");
scriptElement.setAttribute("type", "text/javascript");

document.body.appendChild(scriptElement);

And, there is another advantage to writing greasemonkey scripts this way, you separate out the main javascript from the greasemonkey script. And now you can keep updating your javascript and the users can keep getting the updated functionality without them re-installing the greasemonkey script again. Sweet!

Bookmark and Share

Leave a Comment

install_name_tool to the rescue

I upgraded to Rails 3 and the mysql2 gem. And then:

balpreet-pankajs-macbook:youmash balpreetpankaj$ rake db:create
rake aborted!
dlopen(/opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle, 9): Library not loaded: libmysqlclient.18.dylib
Referenced from: /opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle
Reason: image not found - /opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle

(See full trace by running task with --trace)

This is when install_name_tool came to the rescue. Apparently mysql2 gem is not using the full path to the library. And install_name_tool allows us to change dynamic shared lib names.

So, I did this:

balpreet-pankajs-macbook:youmash balpreetpankaj$ sudo install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.18.dylib /opt/local/lib/ruby/gems/1.8/gems/mysql2-0.3.6/lib/mysql2/mysql2.bundle

And things worked :)

Bookmark and Share

Leave a Comment

Skip Validations

How many times have you felt like skipping validations on a particular model while writing rspec tests ? Last night, I was trying to write rspec tests for one of my models which tested transactions of money between two users. My user model has tens of validations and I totally wanted to skip them all. I just wanted to test the functionality that the money was transacted between the two users correctly. Thats when I used some of Ruby's metaprogramming capabilities to skip validations. Once I was done writing my tests (phew !!) , I decided to turn this into a Rails Plugin, enter SkipValidations ( http://github.com/balpreetspankaj/SkipValidations/tree/master).

This is a very simple plugin. Just install the plugin and then use the skip_validations on any ActiveRecord::Base class and give it the list of models fr which you want no validations. Simple ! for example,

User.skip_validations(:user, :person) {SellRequest.match_requests }

will skip validations for both User and Person model while running the SellRequest.match_requests function. This plugin made my testing a lot more smoother. Hopefully this is useful for you guys too.

Bookmark and Share

Leave a Comment

Facebook Iframe Application: Resize Iframe

If you are using Rails and Facebooker, and you have a resizable Iframe application and you are having problems with resizing, do the following:

a) Make sure that the Iframe is set to Resizable in the Facebook appplication settings.

b) Instead of calling just <%= init_fb_connect "XFBML" %> (as mentioned in all the tutorials), use

<% init_fb_connect "XFBML" do %>
FB.CanvasClient.startTimerToSizeToContent();
<% end %>

This should automatically resize your Iframe in the facebook canvas

Bookmark and Share

Leave a Comment

Facebooker: Creating an Iframe Application (Incorrect Signature)

I started developing a Facebook app for one of my existing websites.  Since, I already had a working website and I prefer normal html and js over fbml and JS over FBML and FBJS, I decided to take the IFrame route. While working with my app, I ran into this bizarre problem where clicking on any link after loading the facebook app, gave me an invalid Signature exception. After digging my way through the Facebooker (Rails plugin for Facebook app dev) code, I find that the expected signature is nil inside the "verify_signature function". Turns out you need to append all your links in a Facebook iframe app with the fb_sig params. So, I created a function in Application.rb and set it as a before_filter

before_filter :set_facebook_params
ensure_application_is_installed_by_facebook_user
 
protected
def set_facebook_params
@fb_params = params.inject({}) do |collection, pair|
collection[pair.first] = pair.second if pair.first =~ /^fb_sig/
collection
end
end

The above code will extract out all the fb_sig params from the url and store it in @fb_params. Now add this hash to every url that you create inside you Iframe. This was the fix that I came in the middle of the might, and I am sure this may not be the best fix. But this works. Let me know if there is another workaround.

Bookmark and Share

Leave a Comment

SMERF and issues with MySQL

SMERF is the meta form generator plugin for Rails. The plugin I would say is very useful. It takes in a form definition file, defined in YAML and creates a form on the fly. These forms are associated to users and the responses to the forms are also persisted in the db. Ideal for making a quick survey for the users on your websites. I was using this plugin to create a survey for the upcoming fashion website chictini.com, and ran into a weird issue.

SMERF plugin, actually parses a form definition YAML file, and creates a SmerfForm object out of it. This SmerfForm object is actually persisted in your db, for fast future accesses. Now this SmerfForm object is serialized into a text field in a MySQL table. Everything works fine when you have small forms. But as soon as your forms get bigger, you hit a MySQL issue. The max size of a text field in MySQL is 64 KB. So if the serialized data is more than 64 KB, you start getting weird errors. The serialization does nnot throw an error, neither does saving the object in DB. But when you try to access the serialized data, you basically get incomplete serialized data, which is nothing but garbage for your purposes.

Solution:  Change the column which stores the serialized data to longtext for MySQL. You can create a migration for this which would look like this:

 
class UpdateColumnInSmerf > ActiveRecord::Migration
def self.up
execute "ALTER TABLE smerf_forms MODIFY COLUMN cache LONGTEXT"
end
 
def self.down
execute "ALTER TABLE smerf_forms MODIFY COLUMN cache TEXT"
end
end
 

This was was one of the annoying issues which kept me awake till 3 am.

Bookmark and Share

Comments (2)

Div inside a p : Invalid HTML

I was trying to center an element using the p tag. Like :
<p style="margin-left:auto; magin-right:auto; width: 50 em;">
<%= show_simple_captcha %>
</p>

show_simple_captcha is a helper method from the simple captcha rails plugin. This view helper generates a div which helps in captcha validation. Now, this created a problem. This piece of code started to behave randomly in IE. Even the source generated in Firefox is invalid HTML. After much scratching arnd, I found that <div> tags are not allowed inside <p> tags. Strange !! I dont have a reason of the top of my head as to why this is disallowed, but this is invalid W3C HTML.

Bookmark and Share

Leave a Comment

action_mailer_tls and Ruby 1.8.7

If you are using action_mailer_tls rails pluin and you shifted to Ruby 1.8.7, your app might break. I recently ran into this problem, coz my host providers shifted to Ruby 1.8.7 and I started getting errors when I was trying to send emails. The problem is because the check_auth_args function has changed in Ruby 1.8.7. Now it requires only 2 args as opposed to 3. The action_mailer_tls plugin uses this function but uses three arguments. So, to get back running again, make the following changes:

1).  Go to your action_mailer_tls plugin installation
2). Inside the do_start function, replace the call to "check_auth_args" with the following snippet:

 
no_args = method(:check_auth_args).arity
if no_args == 2
  check_auth_args user, secret if user or secret
else
  check_auth_args user, secret, authtype if user or secret
end
 
Bookmark and Share

Comments (4)