Patch #27695
closedFix ActiveRecord::RecordNotUnique errors when trying to add certain issue relations
Description
When adding issue relations, under certain conditions, it is not possible for the model validations to check whether a new relation can be added. This results in an ActiveRecord::RecordNotUnique
error to be thrown due to the UNIQUE index on the database.
There are two cases where this can occur:
The first case are race conditions with multiple quick attempts to add the relation which end up on multiple worker processes and are handled concurrently. This is a common (but generally rather unlikely) issue with all unique validations on models.
The second case (which in this case is a logic issue) is triggered if there already are directed relations between issues and a user tries to add the reverse relation. Consider this case:
- There exists a precedes relation between issues 1 and 2.
- The user tries to add a follows relation between issues 2 and 1
- After validation but before save, the new relation is normalized in
Relation#handle_issue_order
to be saved as "1 precedes 2". - A save of this normalized relation triggers the uniqueness constraint on the database and results in an unhandled
ActiveRecord::RecordNotUnique
error
- After validation but before save, the new relation is normalized in
The root cause of the issue is that the normalization happens after validation. This was moved from before_validation
to @before_save
in r3191. I guess his was done so that validation errors do not alter the displayed form with the validation errors.
The attached patch (which I extracted from Planio) tries to deal with this situation by handling the exception in the controller and to add a generic error to the model. This can handle both cases described above without an unhandled exception by showing a suitable error message to all clients.
Files