Skip to content

Commit f82c650

Browse files
author
Vo Minh Thu
committed
[FIX] xmlrpc: handle old/new exceptions with old/new clients.
bzr revid: [email protected]
1 parent 22b1bb8 commit f82c650

File tree

4 files changed

+64
-19
lines changed

4 files changed

+64
-19
lines changed

openerp/exceptions.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Warning(Exception):
3333
class AccessDenied(Exception):
3434
""" Login/password error. No message, no traceback. """
3535
def __init__(self):
36-
super(AccessDenied, self).__init__('AccessDenied.')
36+
super(AccessDenied, self).__init__('Access denied.')
3737
self.traceback = ('', '', '')
3838

3939
class AccessError(Exception):
@@ -52,6 +52,5 @@ class DeferredException(Exception):
5252
def __init__(self, msg, tb):
5353
self.message = msg
5454
self.traceback = tb
55-
self.args = (msg, tb)
5655

5756
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

openerp/netsvc.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ def close_socket(sock):
6363

6464
def abort_response(dummy_1, description, dummy_2, details):
6565
# TODO Replace except_{osv,orm} with these directly.
66-
if description == 'AccessError':
67-
raise openerp.exceptions.AccessError(details)
68-
else:
69-
raise openerp.exceptions.Warning(details)
66+
raise openerp.osv.osv.except_osv(description, detail)
7067

7168
class Service(object):
7269
""" Base class for *Local* services

openerp/osv/osv.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@
3434
from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel
3535
import openerp.exceptions
3636

37-
# For backward compatibility
38-
except_osv = openerp.exceptions.Warning
37+
# Deprecated.
38+
class except_osv(Exception):
39+
def __init__(self, name, value):
40+
self.name = name
41+
self.value = value
42+
self.args = (name, value)
3943

4044
service = None
4145

@@ -115,9 +119,7 @@ def _(src):
115119
raise except_osv('Database not ready', 'Currently, this database is not fully loaded and can not be used.')
116120
return f(self, dbname, *args, **kwargs)
117121
except orm.except_orm, inst:
118-
if inst.name == 'AccessError':
119-
self.logger.debug("AccessError", exc_info=True)
120-
netsvc.abort_response(1, inst.name, 'warning', inst.value)
122+
raise except_osv(inst.name, inst.value)
121123
except except_osv:
122124
raise
123125
except IntegrityError, inst:

openerp/wsgi.py

+55-8
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,15 @@
4848
# User code must use the exceptions defined in ``openerp.exceptions`` (not
4949
# create directly ``xmlrpclib.Fault`` objects).
5050
XML_RPC_FAULT_CODE_APPLICATION_ERROR = 1
51+
# Unused, deferred errors are indistinguishable from normal application
52+
# errors. We keep them so we can use the word 'indistinguishable' twice
53+
# in the same comment.
5154
XML_RPC_FAULT_CODE_DEFERRED_APPLICATION_ERROR = 2
5255
XML_RPC_FAULT_CODE_ACCESS_DENIED = 3
5356
XML_RPC_FAULT_CODE_ACCESS_ERROR = 4
5457
XML_RPC_FAULT_CODE_WARNING = 5
5558

56-
def xmlrpc_return(start_response, service, method, params):
59+
def xmlrpc_return(start_response, service, method, params, legacy_exceptions=False):
5760
"""
5861
Helper to call a service's method with some params, using a wsgi-supplied
5962
``start_response`` callback.
@@ -70,6 +73,20 @@ def xmlrpc_return(start_response, service, method, params):
7073
try:
7174
result = openerp.netsvc.dispatch_rpc(service, method, params)
7275
response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False, encoding=None)
76+
except Exception, e:
77+
if legacy_exceptions:
78+
response = xmlrpc_handle_exception_legacy(e)
79+
else:
80+
response = xmlrpc_handle_exception(e)
81+
start_response("200 OK", [('Content-Type','text/xml'), ('Content-Length', str(len(response)))])
82+
return [response]
83+
84+
def xmlrpc_handle_exception(e):
85+
try:
86+
raise e
87+
except openerp.osv.osv.except_osv, e: # legacy
88+
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_WARNING, openerp.tools.ustr(e.value))
89+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
7390
except openerp.exceptions.Warning, e:
7491
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_WARNING, str(e))
7592
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
@@ -84,17 +101,47 @@ def xmlrpc_return(start_response, service, method, params):
84101
# Which one is the best ?
85102
formatted_info = "".join(traceback.format_exception(*info))
86103
#formatted_info = openerp.tools.exception_to_unicode(e) + '\n' + info
87-
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_DEFERRED_APPLICATION_ERROR, formatted_info)
104+
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_APPLICATION_ERROR, formatted_info)
105+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
106+
except Exception, e:
107+
if hasattr(e, 'message') and e.message == 'AccessDenied': # legacy
108+
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_ACCESS_DENIED, str(e))
109+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
110+
else:
111+
info = sys.exc_info()
112+
# Which one is the best ?
113+
formatted_info = "".join(traceback.format_exception(*info))
114+
#formatted_info = openerp.tools.exception_to_unicode(e) + '\n' + info
115+
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_APPLICATION_ERROR, formatted_info)
116+
response = xmlrpclib.dumps(fault, allow_none=None, encoding=None)
117+
return response
118+
119+
def xmlrpc_handle_exception_legacy(e):
120+
try:
121+
raise e
122+
except openerp.osv.osv.except_osv, e:
123+
fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '')
124+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
125+
except openerp.exceptions.Warning, e:
126+
fault = xmlrpclib.Fault('warning -- Warning\n\n' + str(e), '')
127+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
128+
except openerp.exceptions.AccessError, e:
129+
fault = xmlrpclib.Fault('warning -- AccessError\n\n' + str(e), '')
130+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
131+
except openerp.exceptions.AccessDenied, e:
132+
fault = xmlrpclib.Fault('AccessDenied', str(e))
133+
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
134+
except openerp.exceptions.DeferredException, e:
135+
info = e.traceback
136+
formatted_info = "".join(traceback.format_exception(*info))
137+
fault = xmlrpclib.Fault(openerp.tools.ustr(e.message), formatted_info)
88138
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
89139
except Exception, e:
90140
info = sys.exc_info()
91-
# Which one is the best ?
92141
formatted_info = "".join(traceback.format_exception(*info))
93-
#formatted_info = openerp.tools.exception_to_unicode(e) + '\n' + info
94-
fault = xmlrpclib.Fault(XML_RPC_FAULT_CODE_APPLICATION_ERROR, formatted_info)
142+
fault = xmlrpclib.Fault(openerp.tools.exception_to_unicode(e), formatted_info)
95143
response = xmlrpclib.dumps(fault, allow_none=None, encoding=None)
96-
start_response("200 OK", [('Content-Type','text/xml'), ('Content-Length', str(len(response)))])
97-
return [response]
144+
return response
98145

99146
def wsgi_xmlrpc(environ, start_response):
100147
""" The main OpenERP WSGI handler."""
@@ -138,7 +185,7 @@ def legacy_wsgi_xmlrpc(environ, start_response):
138185
path = environ['PATH_INFO'][len('/xmlrpc/'):] # expected to be one of db, object, ...
139186

140187
params, method = xmlrpclib.loads(data)
141-
return xmlrpc_return(start_response, path, method, params)
188+
return xmlrpc_return(start_response, path, method, params, True)
142189

143190
def wsgi_jsonrpc(environ, start_response):
144191
pass

0 commit comments

Comments
 (0)