-
-
Notifications
You must be signed in to change notification settings - Fork 725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Checkout addresses #5703
Checkout addresses #5703
Conversation
a1c423c
to
48f8e39
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good 👍
I just added some explanatory notes in each commit 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my comment here:
#5702 (comment)
I am convinced that we can make this code change and still keep the constraints relaxed. I dont understand what serious problems the relaxed constraints can create.
I now have feature specs that replicate this bug, and fail at checkout submission, with the expected error (when timestamps are not nullable in the database). The failing specs are fixed by the commits in this PR. |
48f8e39
to
13eecab
Compare
These specs fail with the "NULL values for created_at / updated_at" errors we've been seeing.
In Rails 4, #clone behaves differently. The attributes hash of the cloned object is shared with the original, it's not a separate object! https://github.com/rails/rails/blob/4-0-stable/activerecord/lib/active_record/core.rb#L217-L220
Doing #clone or #dup of an object's attributes then passing it to an #update/#update_attributes call means we are manually passing values for created_at and updated_at, which can cause problems, especially if the object being duped hasn't been persisted yet: in this case we would be manually attempting to save timestamps with nil values, which is not a good idea. Here they are blacklisted from the attributes hash.
I considered deleting these tests, as they're not very good and are testing Rails functionality. I decided to leave them in case something explodes in a future upgrade. For reference: there are issues in Rails 4 when using `object.clone.attributes`, and with assigning a hash containing `created_at` and `updated_at` values with `object.update(attributes_hash)`.
13eecab
to
11da385
Compare
This will be the cause and fix to the multiple stripe payments right Matt? |
I really, really hope so. |
But the root cause was the issue with |
I think problems due to the #clone issue caused an exception, which triggered a rollback, which fucked up, and the combination of some or all of the above possibly then caused an internal issue in postgres itself, on top of all that. What made it hard to spot was this: #5663 (comment) and a missing spec. |
So this is Test ready then? I guess we move it to the top as well? |
I've adjusted the migration here to guard against NULL values whilst the table's NULL constraint is being altered. It needs some re-review and then it would be good to test deploying it to a staging server that does have some NULL timestamps in the database. |
In uk live there are for example orders without these values, I think we will be ok 👍 Let's get another dev to review this before we test. What can go wrong? |
Interesting, there is a single order in UK Prod with NULL values in timestamps. I assume that order could create problems... |
@@ -0,0 +1,253 @@ | |||
class RequireTimestamps < ActiveRecord::Migration | |||
def up | |||
current_time = Time.now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you checked what's the actual value that the ALTER TABLE statement gets called with? It might not matter much in this context but we should always use Rails' Time.zone.now
. It's a bit fuzzy in my memory but I remember Time.now
was a no. What I do know is that calling zone
is the only way to include time-zone information for date times in Rails. According to https://thoughtbot.com/blog/its-about-time-zones we should let AR do the UTC conversion.
It might be fine as it is, but I'd still check this to be fully confident.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! great finding the fact that #change_column_null
allows this option! Before that method, you had to change the schema in graduall and backward-compatible steps.
…straint This argument in #change_column_null assigns this value where any NULL values are found, but it doesn't alter the table's `:default` value
1f708df
to
49fb01a
Compare
Yeah, it's new in Rails 4 🎉 It would have been a huge pain to do this nicely without this option... |
well, it required patience more than anything |
I tested this locally and it works as intended. An order without timestamps (I set them to null from psql) ends up with timestamps set to the current time in UTC and |
Hey @Matt-Yorkley , Checked the 3 scenarios you mentioned, focusing on Stripe-SCA payments: i) guest checkout - OK In iii) I tested 8 different options/combinations of the checkboxes on checkout, inserting new addresses when required
These appear as expected in the dashboard on Stripe. Also inserted a bit random and unusual characters (on addresses, names). In all cases checkout proceeded as expected. Ready to go. |
What? Why?
Closes #5702
Related to #5663 and possibly to #5705
So I think a nasty error was happening (due to the way we were updating default address records) part-way through the transaction for placing and order, which was then aborted/rolled back in a messy way (causing timestamps on associated objects to be NULL), and possibly triggering other issues within postgres itself (see below). Basically there was some really, really nasty stuff happening here that can only be descried as a fail cascade.
There's some related background in this Rails issue in a case where an exception is raised during a transaction at the point that postgres is dealing with caching important values relating to it's internal state (which we actually see some evidence of in the stacktraces on Katuma) and essentially all hell breaks loose: rails/rails#17607
Other related reading: Rails 4 has introduced breaking changes to the behavior of #clone (apparently without mentioning it in the upgrade guide 😒 ), which I think is what caused the problematic exception in this case. See: https://github.com/rails/rails/blob/4-0-stable/activerecord/lib/active_record/core.rb#L217-L220
We didn't see this in the build before, mostly because of this: #5663 (comment) and partly because of a tiny bit of missing spec coverage for a particular case.
What should we test?
We need to very carefully test the "save as default billing address" and "save as default shipping address" checkout options with:
Update: it looks like it's actually just the scenario where the user already has default addresses saved, and they select the "save as default shipping/billing address" option again, which updates their existing default addresses.
Release notes
Fixed bug with updating default addresses during checkout in v3