mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-21 02:32:03 +02:00
18.0 vanilla
This commit is contained in:
parent
d72e748793
commit
0a7ae8db93
337 changed files with 399651 additions and 232598 deletions
|
|
@ -6,20 +6,22 @@ import time
|
|||
from collections.abc import Mapping, Sequence
|
||||
from functools import partial
|
||||
|
||||
from psycopg2 import IntegrityError, OperationalError, errorcodes
|
||||
from psycopg2 import IntegrityError, OperationalError, errorcodes, errors
|
||||
|
||||
import odoo
|
||||
from odoo.exceptions import UserError, ValidationError, AccessError
|
||||
from odoo.models import BaseModel
|
||||
from odoo.http import request
|
||||
from odoo.tools import DotDict
|
||||
from odoo.tools.translate import _, translate_sql_constraint
|
||||
from odoo.modules.registry import Registry
|
||||
from odoo.tools import DotDict, lazy
|
||||
from odoo.tools.translate import translate_sql_constraint
|
||||
|
||||
from . import security
|
||||
from ..tools import lazy
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
PG_CONCURRENCY_ERRORS_TO_RETRY = (errorcodes.LOCK_NOT_AVAILABLE, errorcodes.SERIALIZATION_FAILURE, errorcodes.DEADLOCK_DETECTED)
|
||||
PG_CONCURRENCY_EXCEPTIONS_TO_RETRY = (errors.LockNotAvailable, errors.SerializationFailure, errors.DeadlockDetected)
|
||||
MAX_TRIES_ON_CONCURRENCY_FAILURE = 5
|
||||
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ def dispatch(method, params):
|
|||
|
||||
threading.current_thread().dbname = db
|
||||
threading.current_thread().uid = uid
|
||||
registry = odoo.registry(db).check_signaling()
|
||||
registry = Registry(db).check_signaling()
|
||||
with registry.manage_changes():
|
||||
if method == 'execute':
|
||||
res = execute(db, uid, *params[3:])
|
||||
|
|
@ -65,7 +67,7 @@ def execute_cr(cr, uid, obj, method, *args, **kw):
|
|||
env = odoo.api.Environment(cr, uid, {})
|
||||
recs = env.get(obj)
|
||||
if recs is None:
|
||||
raise UserError(_("Object %s doesn't exist", obj))
|
||||
raise UserError(env._("Object %s doesn't exist", obj))
|
||||
get_public_method(recs, method) # Don't use the result, call_kw will redo the getattr
|
||||
result = retrying(partial(odoo.api.call_kw, recs, method, args, kw), env)
|
||||
# force evaluation of lazy values before the cursor is closed, as it would
|
||||
|
|
@ -80,7 +82,8 @@ def execute_kw(db, uid, obj, method, args, kw=None):
|
|||
|
||||
|
||||
def execute(db, uid, obj, method, *args, **kw):
|
||||
with odoo.registry(db).cursor() as cr:
|
||||
# TODO could be conditionnaly readonly as in _call_kw_readonly
|
||||
with Registry(db).cursor() as cr:
|
||||
res = execute_cr(cr, uid, obj, method, *args, **kw)
|
||||
if res is None:
|
||||
_logger.info('The method %s of the object %s can not return `None`!', method, obj)
|
||||
|
|
@ -90,47 +93,48 @@ def execute(db, uid, obj, method, *args, **kw):
|
|||
def _as_validation_error(env, exc):
|
||||
""" Return the IntegrityError encapsuled in a nice ValidationError """
|
||||
|
||||
unknown = _('Unknown')
|
||||
model = DotDict({'_name': unknown.lower(), '_description': unknown})
|
||||
field = DotDict({'name': unknown.lower(), 'string': unknown})
|
||||
unknown = env._('Unknown')
|
||||
model = DotDict({'_name': 'unknown', '_description': unknown})
|
||||
field = DotDict({'name': 'unknown', 'string': unknown})
|
||||
for _name, rclass in env.registry.items():
|
||||
if exc.diag.table_name == rclass._table:
|
||||
model = rclass
|
||||
field = model._fields.get(exc.diag.column_name) or field
|
||||
break
|
||||
|
||||
if exc.pgcode == errorcodes.NOT_NULL_VIOLATION:
|
||||
return ValidationError(_(
|
||||
"The operation cannot be completed:\n"
|
||||
"- Create/update: a mandatory field is not set.\n"
|
||||
"- Delete: another model requires the record being deleted."
|
||||
" If possible, archive it instead.\n\n"
|
||||
"Model: %(model_name)s (%(model_tech_name)s)\n"
|
||||
"Field: %(field_name)s (%(field_tech_name)s)\n",
|
||||
model_name=model._description,
|
||||
model_tech_name=model._name,
|
||||
field_name=field.string,
|
||||
field_tech_name=field.name,
|
||||
))
|
||||
match exc:
|
||||
case errors.NotNullViolation():
|
||||
return ValidationError(env._(
|
||||
"The operation cannot be completed:\n"
|
||||
"- Create/update: a mandatory field is not set.\n"
|
||||
"- Delete: another model requires the record being deleted."
|
||||
" If possible, archive it instead.\n\n"
|
||||
"Model: %(model_name)s (%(model_tech_name)s)\n"
|
||||
"Field: %(field_name)s (%(field_tech_name)s)\n",
|
||||
model_name=model._description,
|
||||
model_tech_name=model._name,
|
||||
field_name=field.string,
|
||||
field_tech_name=field.name,
|
||||
))
|
||||
|
||||
if exc.pgcode == errorcodes.FOREIGN_KEY_VIOLATION:
|
||||
return ValidationError(_(
|
||||
"The operation cannot be completed: another model requires "
|
||||
"the record being deleted. If possible, archive it instead.\n\n"
|
||||
"Model: %(model_name)s (%(model_tech_name)s)\n"
|
||||
"Constraint: %(constraint)s\n",
|
||||
model_name=model._description,
|
||||
model_tech_name=model._name,
|
||||
constraint=exc.diag.constraint_name,
|
||||
))
|
||||
case errors.ForeignKeyViolation():
|
||||
return ValidationError(env._(
|
||||
"The operation cannot be completed: another model requires "
|
||||
"the record being deleted. If possible, archive it instead.\n\n"
|
||||
"Model: %(model_name)s (%(model_tech_name)s)\n"
|
||||
"Constraint: %(constraint)s\n",
|
||||
model_name=model._description,
|
||||
model_tech_name=model._name,
|
||||
constraint=exc.diag.constraint_name,
|
||||
))
|
||||
|
||||
if exc.diag.constraint_name in env.registry._sql_constraints:
|
||||
return ValidationError(_(
|
||||
return ValidationError(env._(
|
||||
"The operation cannot be completed: %s",
|
||||
translate_sql_constraint(env.cr, exc.diag.constraint_name, env.context.get('lang', 'en_US'))
|
||||
))
|
||||
|
||||
return ValidationError(_("The operation cannot be completed: %s", exc.args[0]))
|
||||
return ValidationError(env._("The operation cannot be completed: %s", exc.args[0]))
|
||||
|
||||
|
||||
def retrying(func, env):
|
||||
|
|
@ -169,7 +173,7 @@ def retrying(func, env):
|
|||
raise RuntimeError(f"Cannot retry request on input file {filename!r} after serialization failure") from exc
|
||||
if isinstance(exc, IntegrityError):
|
||||
raise _as_validation_error(env, exc) from exc
|
||||
if exc.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY:
|
||||
if not isinstance(exc, PG_CONCURRENCY_EXCEPTIONS_TO_RETRY):
|
||||
raise
|
||||
if not tryleft:
|
||||
_logger.info("%s, maximum number of tries reached!", errorcodes.lookup(exc.pgcode))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue