diff --git a/openerp/exceptions.py b/openerp/exceptions.py new file mode 100644 index 00000000000..944e34fb3ef --- /dev/null +++ b/openerp/exceptions.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +class Warning(Exception): + pass + +class AccessDenied(Exception): + """ Login/password error. No message, no traceback. """ + def __init__(self): + import random + super(AccessDenied, self).__init__('Try again. %s out of %s characters are correct.' % (random.randint(0, 30), 30)) + self.traceback = ('', '', '') + +class AccessError(Exception): + """ Access rights error. """ + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 4f9fd3b89ca..7f81228de8c 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -37,6 +37,7 @@ from pprint import pformat # TODO modules that import netsvc only for things from loglevels must be changed to use loglevels. from loglevels import * import tools +import openerp.exceptions def close_socket(sock): """ Closes a socket instance cleanly @@ -60,11 +61,12 @@ def close_socket(sock): #.apidoc title: Common Services: netsvc #.apidoc module-mods: member-order: bysource -def abort_response(error, description, origin, details): - if not tools.config['debug_mode']: - raise Exception("%s -- %s\n\n%s"%(origin, description, details)) +def abort_response(dummy_1, description, dummy_2, details): + # TODO Replace except_{osv,orm} with these directly. + if description == 'AccessError': + raise openerp.exceptions.AccessError(details) else: - raise + raise openerp.exceptions.Warning(details) class Service(object): """ Base class for *Local* services @@ -413,6 +415,12 @@ def dispatch_rpc(service_name, method, params): _log('execution time', '%.3fs' % (end_time - start_time), channel=logging.DEBUG_RPC_ANSWER) _log('result', result, channel=logging.DEBUG_RPC_ANSWER) return result + except openerp.exceptions.AccessError: + raise + except openerp.exceptions.AccessDenied: + raise + except openerp.exceptions.Warning: + raise except Exception, e: _log('exception', tools.exception_to_unicode(e)) tb = getattr(e, 'traceback', sys.exc_info()) diff --git a/openerp/osv/osv.py b/openerp/osv/osv.py index f2f8bb6be23..3c63b5c96d2 100644 --- a/openerp/osv/osv.py +++ b/openerp/osv/osv.py @@ -117,7 +117,7 @@ class object_proxy(): self.logger.debug("AccessError", exc_info=True) netsvc.abort_response(1, inst.name, 'warning', inst.value) except except_osv, inst: - netsvc.abort_response(1, inst.name, inst.exc_type, inst.value) + netsvc.abort_response(1, inst.name, 'warning', inst.value) except IntegrityError, inst: osv_pool = pooler.get_pool(dbname) for key in osv_pool._sql_error.keys(): diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index f0e38d9743f..181c7a25b78 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -38,6 +38,7 @@ import openerp.release as release import openerp.sql_db as sql_db import openerp.tools as tools import openerp.modules +import openerp.exceptions #.apidoc title: Exported Service methods #.apidoc module-mods: member-order: bysource @@ -302,7 +303,7 @@ class db(netsvc.ExportService): def exp_list(self, document=False): if not tools.config['list_db'] and not document: - raise Exception('AccessDenied') + raise openerp.exceptions.AccessDenied() db = sql_db.db_connect('template1') cr = db.cursor() @@ -356,7 +357,7 @@ class db(netsvc.ExportService): except except_orm, inst: netsvc.abort_response(1, inst.name, 'warning', inst.value) except except_osv, inst: - netsvc.abort_response(1, inst.name, inst.exc_type, inst.value) + netsvc.abort_response(1, inst.name, 'warning', inst.value) except Exception: import traceback tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback)) diff --git a/openerp/wsgi.py b/openerp/wsgi.py index b407800db9a..f1886a4cb37 100644 --- a/openerp/wsgi.py +++ b/openerp/wsgi.py @@ -38,6 +38,7 @@ import threading import time import openerp +import openerp.modules import openerp.tools.config as config import service.websrv_lib as websrv_lib @@ -49,8 +50,18 @@ def xmlrpc_return(start_response, service, method, params): try: result = openerp.netsvc.dispatch_rpc(service, method, params) response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False, encoding=None) + except openerp.exceptions.AccessError, e: + fault = xmlrpclib.Fault(5, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + except openerp.exceptions.Warning, e: + fault = xmlrpclib.Fault(4, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + except openerp.exceptions.AccessDenied, e: + fault = xmlrpclib.Fault(3, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) except openerp.netsvc.OpenERPDispatcherException, e: - fault = xmlrpclib.Fault(2, openerp.tools.exception_to_unicode(e.exception) + '\n' + e.traceback) # TODO map OpenERP-specific exception to some fault code + # TODO collapse this case with the next one. + fault = xmlrpclib.Fault(2, openerp.tools.exception_to_unicode(e.exception) + '\n' + e.traceback) response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) except: exc_type, exc_value, exc_tb = sys.exc_info()