gocardless / statesman

A statesmanlike state machine library.
https://gocardless.com/blog/statesman/
MIT License
1.78k stars 163 forks source link

How come I get a lot of sort_key uniqueness validation errors? #333

Closed ericgross closed 4 years ago

ericgross commented 5 years ago

Frequently I'll get this error in statesman 3.5.0 from my background jobs:

Validation failed: Sort key has already been taken

from this line of code:

Statesman::Machine.retry_conflicts(1) { order.transition_to!(:recipe_customized) }

I see that retry_conflicts only rescues from TransitionConflictError exceptions - but I think it should also rescue from (and retry) the error I am seeing - is that right?

danwakefield commented 5 years ago

Statesman should be raising TransitionConflictError in this case. See below.

https://github.com/gocardless/statesman/blob/50640ee26da095927ae356f1fb95759563b23267/lib/statesman/adapters/active_record.rb#L35-L40

https://github.com/gocardless/statesman/blob/50640ee26da095927ae356f1fb95759563b23267/lib/statesman/adapters/active_record.rb#L120-L123

Can you tell me the Database and version you are using and I'll try to figure out if transition_conflict_error? should be changed in some way.

My immediate thought is that the error you are receiving is from ActiveRecord model validations (See the default error message here https://guides.rubyonrails.org/active_record_validations.html#uniqueness)

Statesman only retry's when the error has come from the database from a constraint. You could remove the validation and rely on the constraint to fix things.

You could also monkey-patch the create method above to catch ActiveRecord::RecordInvalid and turn it into a TransitionConflictError