Reporting errors to the user

During method execution, it is sometimes necessary to abort the processing because an error condition was met. This recipe shows how to do this so that a helpful error message is displayed to the user when a method which writes a file to disk encounters an error.

Getting ready

To use this recipe, you need a method, which can have an abnormal condition. We will use the following one:

import os
from openerp import models, fields, api

class SomeModel(models.Model):
    data = fields.Text('Data')

    @api.multi
    def save(self, filename):
        path = os.path.join('/opt/exports', filename)
        with open(path, 'w') as fobj:
            for record in self:
                fobj.write(record.data)
                fobj.write('
')

This method can fail because of permission issues, or a full disk, or an illegal name, which would cause an IOError or an OSError exception to be raised.

How to do it…

To display an error message to the user when an error condition is encountered, you need to take the following steps:

  1. Add the following import at the beginning of the Python file:
    from openerp.exceptions import UserError
  2. Modify the method to catch the exception raised and raise a UserError exception:
        @api.multi
        def save(self, filename):
            if '/' in filename or '' in filename:
                raise UserError('Illegal filename %s' % filename)
            path = os.path.join('/opt/exports', filename)
            try:
                with open(path, 'w') as fobj:
                    for record in self:
                        fobj.write(record.data)
                        fobj.write('
    ')
            except (IOError, OSError) as exc:
                message = 'Unable to save file: %s' % exc
                raise UserError(message)

How it works…

When an exception is raised in Python, it propagates up the call stack until it is processed. In Odoo, the RPC layer that answers the calls made by the web client catches all exceptions and, depending on the exception class, it will trigger different possible behaviors on the web client.

Any exception not defined in openerp.exceptions will be handled as an Internal Server Error (HTTP status 500), with the stack trace. A UserError will display an error message in the user interface. The code of the recipe changes the OSError to a UserError to ensure the message is displayed in a friendly way. In all cases, the current database transaction is rolled back.

Of course, it is not required to catch an exception with a try..except, construct to raise a UserError exception. It is perfectly OK to test for some condition, such as the presence of illegal characters in a filename, and to raise the exception when that test is True. This will prevent further processing of the user request.

There's more…

There are a few more exception classes defined in openerp.exceptions, all deriving the base legacy except_orm exception class. Most of them are only used internally, apart from the following:

  • Warning: In Odoo 8.0, openerp.exceptions.Warning played the role of UserError in 9.0. It is now deprecated because the name was deceptive (it is an error, not a warning) and it collided with the Python built-in Warning class. It is kept for backward compatibility only and you should use UserError in 9.0.
  • ValidationError: This exception is raised when a Python constraint on a field is not respected. In Chapter 4, Application Models, refer to the Adding constraint validations to a Model recipe for more information.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset