[FIX] base: clearer message in case of conflict for no_gap sequences
The raw error message from psycopg2 wasn't clear for users and led to multiple support tickets. In case of such "concurrency" errors, the user should retry later, it's not a "real" bug. closes odoo/odoo#57851 X-original-commit: 9f7f1db5add5b8a940e53707091133c0bcadd350 Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
import pytz
|
||||
from psycopg2 import sql
|
||||
from psycopg2 import sql, OperationalError, errorcodes
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
@@ -53,8 +53,14 @@ def _select_nextval(cr, seq_name):
|
||||
|
||||
def _update_nogap(self, number_increment):
|
||||
number_next = self.number_next
|
||||
self._cr.execute("SELECT number_next FROM %s WHERE id=%%s FOR UPDATE NOWAIT" % self._table, [self.id])
|
||||
self._cr.execute("UPDATE %s SET number_next=number_next+%%s WHERE id=%%s " % self._table, (number_increment, self.id))
|
||||
try:
|
||||
self._cr.execute("SELECT number_next FROM %s WHERE id=%%s FOR UPDATE NOWAIT" % self._table, [self.id])
|
||||
self._cr.execute("UPDATE %s SET number_next=number_next+%%s WHERE id=%%s " % self._table, (number_increment, self.id))
|
||||
except OperationalError as e:
|
||||
if e.pgcode == errorcodes.LOCK_NOT_AVAILABLE:
|
||||
raise UserError(_("This transaction wasn't executed because another transaction is already using the same no-gap sequence. Please try again later."))
|
||||
else:
|
||||
raise
|
||||
self.invalidate_cache(['number_next'], [self.id])
|
||||
return number_next
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import psycopg2
|
||||
import psycopg2.errorcodes
|
||||
|
||||
import odoo
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import common
|
||||
from odoo.tests.common import BaseCase
|
||||
|
||||
@@ -92,11 +93,10 @@ class TestIrSequenceNoGap(BaseCase):
|
||||
with environment() as env0:
|
||||
with environment() as env1:
|
||||
env1.cr._default_log_exceptions = False # Prevent logging a traceback
|
||||
with self.assertRaises(psycopg2.OperationalError) as e:
|
||||
with self.assertRaises(UserError) as e:
|
||||
n0 = env0['ir.sequence'].next_by_code('test_sequence_type_2')
|
||||
self.assertTrue(n0)
|
||||
n1 = env1['ir.sequence'].next_by_code('test_sequence_type_2')
|
||||
self.assertEqual(e.exception.pgcode, psycopg2.errorcodes.LOCK_NOT_AVAILABLE, msg="postgresql returned an incorrect errcode")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
|
||||
Reference in New Issue
Block a user