This removes a hack in the code that's designed to work around a
rest-client bug which was added back in 2011. Unfortunately neither
comments nor commit messages bother to tell us what the nature of the
bug actually was, but based on what it's rescuing, it might be
rest-client/rest-client#58, which has been fixed for over five years
now.
Following up on the work done in #436, let's continue to try and simply
the error handling paths by taking this out.
Two changes:
1. The HTTP retry path has been refactored to make retries on errors
that are not RestClient exceptions possible by bringing the logic up a
level. This also has the effect of somewhat simplifying the exception
handling logic which can be somewhat difficult to reason about right
now.
2. Retry on `RestClient::Conflict` (a 409 from the API) as discussed in
issue #431.
Fixes#431.
Introduce a `#save_with_parent` flag that allows the default behavior of
never saving API resources nested under a parent to be overridden, a
feature that we so far only know to need for updating a source under a
customer.
CI is failing for a number of Ruby versions because shoulda is pulling
in should-matchers, which then pulls in activesupport. activesupport's
new 5.0.0 version is being picked up, and that requires at least Ruby
2.2.2.
Luckily the solution is easy, we're not using shoulda-matchers, only
shoulda-context, so just tighten up our dependencies a little and the
problem goes away.
* Rename the `Update` operation to `Save`
* Add the `update` class method to all saveable resources
* Add tests for update method
* Add tests for plans, invoice items, and application fees
* allow subs to be retrieved & created with new v1/subs API endpoint
* edit tests to check for url
* fix customer subscription URLs to go through v1/customers
- When performing requests on the behalf of a managed account, `stripe_account` option must be passed everytime, this can become redundant
- Allowing to set the `stripe_account` globally makes thing easier for wrapping every request in a single method, the same way as it is for defining the `api_key` globally
I'm not sure exactly what changed here (did we change the `$VERBOSE`
setting?), but I'm not seeing a whole lot of warnings when running the
test suites locally and in CI. For example:
```
Started
........................................./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
............../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
.../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
........./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
...
..../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
....../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
..../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
........./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
........../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
................./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
.../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
..../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
....../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
..........
........./home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
....../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
......../home/travis/build/stripe/stripe-ruby/lib/stripe/api_operations/list.rb:6: warning: instance variable @opts not initialized
............./home/travis/build/stripe/stripe-ruby/lib/stripe/stripe_object.rb:35: warning: instance variable @values not initialized
./home/travis/build/stripe/stripe-ruby/lib/stripe/stripe_object.rb:35: warning: instance variable @values not initialized
...................../home/travis/build/stripe/stripe-ruby/lib/stripe/transfer.rb:8: warning: instance variable @api_key not initialized
..............
..
Finished in 0.785621037 seconds.
```
Most of these are due to unused or uninitialized variables. This patch
fixes all warnings by fixing offending code.
This is consistent with API library behavior in other languages, and with our
API documentation (which doesn't mention needing to handle this type of error).
Prior to my last major serialization refactor, there was a check in the
code that would remove any subobjects from serialization that were of
their own proper resource type (for example, if a charge contained a
customer, that customer would be removed).
What I didn't realize at the time is that the old serialization code had
a bug/quirk that would allow *certain types* of subobjects that were API
resources to make it through unscathed.
In short, the behavior requirement here is *directly* contradictory.
There was a test in place that would make sure that `customer` was
removed from this hash:
``` ruby
{
:id => 'ch_id',
:object => 'charge',
:customer => {
:object => 'customer',
:id => 'customer_id'
}
}
```
But, as reported in #406, we expect, and indeed need, for `source` (a
card) to make it through to the API in this hash:
``` ruby
{
:id => 'cus_id',
:object => 'customer',
:source => {
:object => 'card',
:id => 'card_id'
}
}
```
My proposal here is to just remove the check on serializing API
resources. The normal code that only sends up keys/hashes that have
changed is still in place, so in the first example, `customer` still
isn't sent unless the user has directly manipulated a field on that
subobject. I propose that in those cases we allow the API itself to
reject the request rather than try to cut it off at the client level.
Unfortunately, there is some possibility that removing those API
resources is important for some reason, but of course there's no
documentation on it beyond the after-the-fact post-justification that I
wrote during my last refactor. I can't think of any reason that it would
be too destructive, but there is some level of risk.