Monday, August 31, 2015

Element not found in the cache - perhaps the page has changed since it was looked up

The workaround is to add a sleep call for 3 seconds. Let me know if there is a better solution.

WARNING: VCR::RSpec::Macros is deprecated. Use RSpec metadata options instead `:vcr => vcr_options`

Change this:

RSpec.configure do |config|
  config.extend VCR::RSpec::Macros #deprecated
end

to :

VCR.configure do |config|
  config.configure_rspec_metadata!
end

Saturday, August 29, 2015

Fail Early and Loudly

One of the things I learned the hard way is that a software should fail loudly. If you fail silently, it becomes very difficult to find the cause of the problem and fix it quickly. Raise exception as close as possible to the failure so that we can quickly figure out the issue. The exception should contain all the relevant data, the location and the likely cause of failure.

The concept of failing loudly is discussed in the Code Complete 2 book by Steve McConnell. If you just read the theory, you need to expose yourself to that theory repeatedly so that you will be able to apply it in practice. If you learn by experience it becomes easier to grasp that theory quickly and you will never forget it.

Example 1:

One of the gems that I developed requires Ruby 2.2.2 or above. When I did:

$ gem install merlot
Fetching: posix-spawn-0.3.11.gem (100%)
Building native extensions.  This could take a while...
Successfully installed posix-spawn-0.3.11
Fetching: pdf-core-0.6.0.gem (100%)
Successfully installed pdf-core-0.6.0
Fetching: ttfunk-1.4.0.gem (100%)
Successfully installed ttfunk-1.4.0
Fetching: prawn-2.0.2.gem (100%)
Successfully installed prawn-2.0.2
Fetching: merlot-0.1.0.gem (100%)t.1.0.gem
ERROR:  Error installing merlot:
merlot requires Ruby version >= 2.2.2.

Boom! The command fails at the very last step. It does not fail early. The precondition must be checked before wasting time by installing all the dependent gems.

Example 2 :

I turned off my WiFi and did:

$ gem install bacardi
ERROR:  Could not find a valid gem 'bacardi' (>= 0), here is why:
          Unable to download data from https://rubygems.org/ - no such name (https://rubygems.org/specs.4.8.gz)

The error message I receive has no indication on how the user can recover from this problem. Ideally, we want our software to check for the precondition to be satisfied. In this case, a valid Internet connection. This also happens when I am at Starbucks and I have connected to the WiFi but I have not agreed to the terms and conditions. Wouldn't it be better to catch this particular exception and provide a clear message to the user like:

'We have detected a problem with your Internet connection. Please check your connection and try again.'.

The software we develop following this principle would be user friendly and robust under abnormal conditions.

Example 3 :

I worked on a Rails project where one of the gems in the Gemfile used a private gem repository on github. The Gemfile used :github to specify the private gem location, when I ran bundle install, I got the error:

Fetching gem metadata from https://rubygems.org/.Retrying dependency api due to error (2/4): Bundler::HTTPError Network error while fetching 

https://bundler.rubygems.org/api/v1/dependencies?gems=rack-netscaler,rack-timeout,sprockets-rails,rails,rainbow,rdoc,ref,rspec-support,rspec-expectations,rspec-collection_matchers,rspec-core,rspec-example_steps,rspec-mocks,rspec-rails,ruby-progressbar,rubocop,rubyzip,sass-rails,sdoc,websocket,selenium-webdriver,simplecov-html,simplecov,spring,therubyracer,typhoeus,uglifier,vcr,vcr-helper,web-console,webmock

The actual error message has nothing to do with the cause. It turns out that I did not have access to that repository and the admin had to add me as one of the contributor to that repository. Wouldn't it be nice, if either the Bundler or the Github API provided a clear message stating the cause and how to fix it by providing a link for reference? 

Saturday, August 22, 2015

Paypal Express Checkout Error

Problem :

Security header is not valid", "ErrorCode"=>"10002"

Solution:

This error is shown when you are not properly logged into the sandbox account on paypal's site.

0. Login to www.paypal.com
1. Go to https://developer.paypal.com/developer/accounts
2. Copy API credentials for a sandox user with Business-Pro account.

1. Login to sandbox.paypal.com
2. Got to your site and checkout
3. When sent to paypal, login as one of your buyer test accounts

Resources

1. Bogus gateway to test PayPal
https://github.com/sideshowcoder/active_merchant/blob/192f49762172dc41450d7a3605158d45eb55b83b/lib/active_merchant/billing/gateways/paypal_bogus.rb
2. Classic API Endpoints
https://developer.paypal.com/webapps/developer/docs/classic/api/endpoints/
3. Merchant SDK Ruby
https://github.com/paypal/merchant-sdk-ruby
4. How to create and process an order using Express Checkout
https://developer.paypal.com/docs/classic/express-checkout/ht_ec-orderAuthPayment-curl-etc/
5. Sample Webapp that generates SDK code to use
https://paypal-sdk-samples.herokuapp.com/merchant/get_express_checkout_details

Thursday, August 20, 2015

missing files in gem after gem build

Bundler works in a weird way. The files that are not checked in to git will not get included. You have to add all the files to the git and then run gem build. You can verify it has included all the files by running gem unpack and opening the unpacked directory to verify the new files.

Thursday, August 13, 2015

Using RSpec with Ruby Gem

You can generate the required files when you create the directory structure for a gem by doing :

bundler gem --test=rspec my_gem

If you have already created the gem skeleton, it uses Minitest by default. You can make the following changes to switch to rspec:

1. Add :

spec.add_development_dependency "rspec"

to .gemspec file. Run bundle install.

2. Create Rakefile in the root of the gem:

require "bundler/gem_tasks"
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)

task :default => :spec

3. Create spec/spec_helper.rb:

$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)

require 'your-gem'

4. Create spec/yukon_spec.rb:

require 'spec_helper'

describe 'Your Gem' do
  it 'has a version number' do
    expect(YourGem::VERSION).not_to be nil
  end

  it 'does something useful' do
    expect(false).to eq(true)
  end
end

5. Run it:

rspec spec/yukon_spec.rb --color --format doc

Tuesday, August 11, 2015

Problem during RVM installation on Mac OS

Problem :

gpg: no valid OpenPGP data found.

Solution :

gpg --keyserver hkp://keys.gnupg.net:80 --recv-keys D39DC0E3

to force it to talk port 8