diff --git a/openerp/addons/base/ir/ir_fields.py b/openerp/addons/base/ir/ir_fields.py index 7a4c34c7f30..c7012525961 100644 --- a/openerp/addons/base/ir/ir_fields.py +++ b/openerp/addons/base/ir/ir_fields.py @@ -2,6 +2,7 @@ import functools import operator import itertools +import psycopg2 from openerp.osv import orm, fields from openerp.tools.translate import _ @@ -179,14 +180,27 @@ class ir_fields_converter(orm.Model): if context is None: context = {} id = None warnings = [] + extras = {'moreinfo': { + 'type': 'ir.actions.act_window', 'target': 'new', + 'res_model': column._obj, 'view_mode': 'tree,form', + 'view_type': 'form', + 'views': [(False, 'tree', (False, 'form'))], + 'help': _(u"See all possible values") + }} RelatedModel = self.pool[column._obj] if subfield == '.id': field_type = _(u"database id") try: tentative_id = int(value) except ValueError: tentative_id = value - if RelatedModel.search(cr, uid, [('id', '=', tentative_id)], - context=context): - id = tentative_id + try: + if RelatedModel.search(cr, uid, [('id', '=', tentative_id)], + context=context): + id = tentative_id + except psycopg2.DataError: + # type error + raise ValueError( + _(u"Invalid database id '%s' for the field '%%(field)s'") % value, + extras) elif subfield == 'id': field_type = _(u"external id") if '.' in value: @@ -217,17 +231,7 @@ class ir_fields_converter(orm.Model): if id is None: raise ValueError( _(u"No matching record found for %(field_type)s '%(value)s' in field '%%(field)s'") - % {'field_type': field_type, 'value': value}, { - 'moreinfo': { - 'type': 'ir.actions.act_window', - 'target': 'new', - 'res_model': column._obj, - 'view_mode': 'tree,form', - 'view_type': 'form', - 'views': [(False, 'tree', (False, 'form'))], - 'help': _(u"See all possible values") - } - }) + % {'field_type': field_type, 'value': value}, extras) return id, field_type, warnings def _referencing_subfield(self, record): diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index da0c93762bc..9a25e621023 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -1335,7 +1335,15 @@ class BaseModel(object): self._extract_records(cr, uid, fields, data, context=context, log=messages.append), context=context, log=messages.append): - cr.execute('SAVEPOINT model_load_save') + try: + cr.execute('SAVEPOINT model_load_save') + except psycopg2.InternalError, e: + # broken transaction, exit and hope the source error was + # already logged + if not any(message['type'] == 'error' for message in messages): + messages.append(dict(info, type='error',message= + u"Unknown database error: '%s'" % e)) + break try: ids.append(ModelData._update(cr, uid, self._name, current_module, record, mode=mode, xml_id=xid, @@ -1349,7 +1357,7 @@ class BaseModel(object): # avoid broken transaction) and keep going cr.execute('ROLLBACK TO SAVEPOINT model_load_save') messages.append(dict( - info, type="error", + info, type='error', **PGERROR_TO_OE[e.pgcode](self, fg, info, e))) if any(message['type'] == 'error' for message in messages): cr.execute('ROLLBACK TO SAVEPOINT model_load') diff --git a/openerp/tests/addons/test_impex/tests/test_load.py b/openerp/tests/addons/test_impex/tests/test_load.py index c141e62b65d..074b75a9fb3 100644 --- a/openerp/tests/addons/test_impex/tests/test_load.py +++ b/openerp/tests/addons/test_impex/tests/test_load.py @@ -619,6 +619,16 @@ class test_m2o(ImporterCase): for index, id in enumerate([integer_id1, integer_id2, integer_id1])]) self.assertIs(result['ids'], False) + @mute_logger('openerp.sql_db') + def test_fail_id_mistype(self): + result = self.import_(['value/.id'], [["foo"]]) + + self.assertEqual(result['messages'], [ + message(u"Invalid database id 'foo' for the field 'unknown'", + moreinfo=moreaction('export.integer')) + ]) + self.assertIs(result['ids'], False) + def test_sub_field(self): """ Does not implicitly create the record, does not warn that you can't import m2o subfields (at all)...