When encountering StaleObjectError when checking out, retry

This commit is contained in:
Rohan Mitchell
2015-06-30 12:50:52 +10:00
parent d0b7a0795d
commit 8deb4ef9d4
2 changed files with 42 additions and 3 deletions

View File

@@ -23,7 +23,7 @@ class CheckoutController < Spree::CheckoutController
return if redirect_to_paypal_express_form_if_needed
end
if @order.next
if advance_order_state(@order)
state_callback(:after)
else
if @order.errors.present?
@@ -83,6 +83,19 @@ class CheckoutController < Spree::CheckoutController
params[:order]
end
def advance_order_state(order)
result = false
tries = 3
begin
result = order.next
rescue ActiveRecord::StaleObjectError
retry unless (tries -= 1).zero?
end
result
end
def update_failed
clear_ship_address

View File

@@ -55,7 +55,7 @@ describe CheckoutController do
it "doesn't copy the previous shipping address from a pickup order" do
old_order = create(:order, bill_address: create(:address), ship_address: create(:address))
Spree::Order.stub_chain(:order, :where, :where, :limit, :detect).and_return(old_order)
controller.send(:find_last_used_addresses, "email").last.should == nil
controller.send(:find_last_used_addresses, "email").last.should == nil
end
describe "building the order" do
@@ -69,7 +69,7 @@ describe CheckoutController do
get :edit
assigns[:order].ship_address.address1.should be_nil
end
it "clears the ship address when re-rendering edit" do
controller.should_receive(:clear_ship_address).and_return true
order.stub(:update_attributes).and_return false
@@ -119,6 +119,32 @@ describe CheckoutController do
response.status.should == 200
response.body.should == {path: spree.order_path(order)}.to_json
end
describe "stale object handling" do
it "retries when a stale object error is encountered" do
order.stub(:update_attributes).and_return true
controller.stub(:state_callback)
# The first time, raise a StaleObjectError. The second time, succeed.
order.stub(:next).once.
and_raise(ActiveRecord::StaleObjectError.new(Spree::Variant.new, 'update'))
order.stub(:next).once do
order.update_column :state, 'complete'
true
end
xhr :post, :update, order: {}, use_route: :spree
response.status.should == 200
end
it "tries a maximum of 3 times before giving up and returning an error" do
order.stub(:update_attributes).and_return true
order.stub(:next) { raise ActiveRecord::StaleObjectError.new(Spree::Variant.new, 'update') }
xhr :post, :update, order: {}, use_route: :spree
response.status.should == 400
end
end
end
describe "Paypal routing" do