[IMP] xmlrpc: use proper exception type to map to xmlrpc error codes.

bzr revid: vmt@openerp.com-20110926151403-fhx4ph22tua2s3st
This commit is contained in:
Vo Minh Thu 2011-09-26 17:14:03 +02:00
parent bbd10d96c0
commit 157580b8e8
5 changed files with 64 additions and 8 deletions

36
openerp/exceptions.py Normal file
View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2011 OpenERP s.a. (<http://openerp.com>).
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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:

View File

@ -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())

View File

@ -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():

View File

@ -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))

View File

@ -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()