diff options
| author | Goffin Simon <simon.goffin@outlook.com> | 2014-12-18 16:38:09 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2015-01-16 17:15:18 +0100 |
| commit | 0fd773a486fbc1aeef7f00ec5eab3eaf0e4c6a9d (patch) | |
| tree | e0b6ab3c1d7c21a2539235805912ee82efd4f23a /addons/portal | |
| parent | eeb8ed165d713f41d7cde33e46acd7accef722fb (diff) | |
[IMP] Cleanup and refactoring of exception handling
Unify and refactor exception handling in framework and addons.
The generic `except_osv` is now deprecated, and replaced by more specialized exception subtypes:
- `UserError` (renamed from Warning, as it conflicts with the built-in `Warning`) raised when a non-technical error occurs during a business operation. It could be a missing information in the data provided by the user, or a misconfiguration.
- `AccessError`: raised when any operation is denied because the user conducting it does not have the required access rights.
- `AccessDenied`: raised when an operation that requires authenticated access is attempted via an unauthenticated request.
- `MissingError`: raised when an operation is attempted on a record that does not exist.
- `ValidationError`: raised when an operation violates a SQL or Python constraint.
- All other exceptions are internal errors due to a system problem or bug, and raised untouched to the client-side, which should display a traceback.
All exceptions take a single message argument.
The `test_exceptions` module has been updated to showcase both new and old (deprecated) exceptions.
A great many old `except_osv` had a useless title with "Error!" or "Warning", those have been removed, as this is handled by the client-side widget that displays the messages.
This commit introduces a more consistent policy for logging errors and warnings:
- All messages that do not require administrator attention should be logged at INFO level or lower. This includes all errors that are notified to the user in a friendly manner, even for access right problems or validation errors during business operations.
- All messages that indicate a likely misconfiguration or malicious use by the users should be logged at WARNING level, as they typically require administrator attention.
- All other unhandled internal errors cannot typically be handled by the user and should be logged at ERROR or higher level, as they require immediate administrator attention.
Diffstat (limited to 'addons/portal')
| -rw-r--r-- | addons/portal/mail_message.py | 6 | ||||
| -rw-r--r-- | addons/portal/tests/test_portal.py | 9 | ||||
| -rw-r--r-- | addons/portal/wizard/portal_wizard.py | 6 |
3 files changed, 10 insertions, 11 deletions
diff --git a/addons/portal/mail_message.py b/addons/portal/mail_message.py index 36b06484e9e..a54b4f423c4 100644 --- a/addons/portal/mail_message.py +++ b/addons/portal/mail_message.py @@ -20,7 +20,8 @@ ############################################################################## from openerp import SUPERUSER_ID -from openerp.osv import osv, orm +from openerp.osv import osv +from openerp.exceptions import AccessError from openerp.tools.translate import _ @@ -56,8 +57,7 @@ class mail_message(osv.Model): if group_user_id not in [group.id for group in group_ids]: cr.execute('SELECT DISTINCT id FROM "%s" WHERE type = %%s AND subtype_id IS NULL AND id = ANY (%%s)' % (self._table), ('comment', ids,)) if cr.fetchall(): - raise orm.except_orm(_('Access Denied'), - _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \ + raise AccessError(_('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % \ (self._description, operation)) return super(mail_message, self).check_access_rule(cr, uid, ids=ids, operation=operation, context=context) diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py index 6a8242bf0cf..6e23ca3d50c 100644 --- a/addons/portal/tests/test_portal.py +++ b/addons/portal/tests/test_portal.py @@ -21,7 +21,6 @@ from openerp.addons.mail.tests.common import TestMail from openerp.exceptions import AccessError -from openerp.osv.orm import except_orm from openerp.tools.misc import mute_logger @@ -60,7 +59,7 @@ class test_portal(TestMail): # Do: Chell browses Pigs -> ko, employee group chell_pigs = self.mail_group.browse(cr, self.user_chell_id, self.group_pigs_id) - with self.assertRaises(except_orm): + with self.assertRaises(AccessError): trigger_read = chell_pigs.name # Do: Chell posts a message on Pigs, crash because can not write on group or is not in the followers @@ -77,7 +76,7 @@ class test_portal(TestMail): if partner.id == self.partner_chell_id: # Chell can read her own partner record continue - with self.assertRaises(except_orm): + with self.assertRaises(AccessError): trigger_read = partner.name # Do: Chell comments Pigs, ok because he is now in the followers @@ -99,7 +98,7 @@ class test_portal(TestMail): for message in chell_port.message_ids: trigger_read = message.subject for partner in chell_port.message_follower_ids: - with self.assertRaises(except_orm): + with self.assertRaises(AccessError): trigger_read = partner.name def test_10_mail_invite(self): @@ -225,5 +224,5 @@ class test_portal(TestMail): self.mail_message.read(cr, self.user_chell_id, msg_ids, ['body', 'type', 'subtype_id']) # Do: Chell read a message she should not be able to read - with self.assertRaises(except_orm): + with self.assertRaises(AccessError): self.mail_message.read(cr, self.user_chell_id, [msg4_id], ['body', 'type', 'subtype_id']) diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py index 24158b41448..0571941b950 100644 --- a/addons/portal/wizard/portal_wizard.py +++ b/addons/portal/wizard/portal_wizard.py @@ -25,6 +25,7 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp.tools import email_split from openerp import SUPERUSER_ID +from openerp.exceptions import UserError _logger = logging.getLogger(__name__) @@ -160,7 +161,7 @@ class wizard_user(osv.osv_memory): def action_apply(self, cr, uid, ids, context=None): error_msg = self.get_error_messages(cr, uid, ids, context=context) if error_msg: - raise osv.except_osv(_('Contacts Error'), "\n\n".join(error_msg)) + raise UserError( "\n\n".join(error_msg)) for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context): portal = wizard_user.wizard_id.portal_id @@ -222,8 +223,7 @@ class wizard_user(osv.osv_memory): this_context = context this_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context) if not this_user.email: - raise osv.except_osv(_('Email Required'), - _('You must have an email address in your User Preferences to send emails.')) + raise UserError(_('You must have an email address in your User Preferences to send emails.')) # determine subject and body in the portal user's language user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) |
