From 3fe8bf10a8e7353db08cba69a9a2969ab6530832 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Mon, 12 Jul 2010 22:29:30 +0300 Subject: [PATCH] Doc WebDAV: More consistent exceptions The NotFound one should properly parse the list uri2. Define a helper function that will wrap around usual calls and handle their exceptions. bzr revid: p_christ@hol.gr-20100712192930-necdd0z9d2j6w4ut --- addons/document_webdav/dav_fs.py | 80 ++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 880074173ea..3805566f79d 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -46,6 +46,15 @@ CACHE_SIZE=20000 urlparse.uses_netloc.append('webdav') urlparse.uses_netloc.append('webdavs') +class DAV_NotFound2(DAV_NotFound): + """404 exception, that accepts our list uris + """ + def __init__(self, *args): + if len(args) and isinstance(args[0], (tuple, list)): + path = ''.join([ '/' + x for x in args[0]]) + args = (path, ) + DAV_NotFound.__init__(self, *args) + class openerp_dav_handler(dav_interface): """ This class models a OpenERP interface for the DAV server @@ -74,6 +83,36 @@ class openerp_dav_handler(dav_interface): cr.close() return props + def _try_function(self, funct, args, opname='run function', cr=None, default_exc=DAV_Forbidden): + """ Try to run a function, and properly convert exceptions to DAV ones. + + @objname the name of the operation being performed + @param cr if given, the cursor to close at exceptions + """ + + try: + funct(*args) + except DAV_Error: + if cr: cr.close() + raise + except NotImplementedError, e: + if cr: cr.close() + import traceback + self.parent.log_error("Cannot %s: %s", opname, str(e)) + self.parent.log_message("Exc: %s",traceback.format_exc()) + raise DAV_Error(405, str(e) or 'Not supported at this path') + except EnvironmentError, err: + if cr: cr.close() + import traceback + self.parent.log_error("Cannot %s: %s", opname, e.strerror) + self.parent.log_message("Exc: %s",traceback.format_exc()) + raise default_exc(err.strerror) + except Exception,e: + import traceback + self.parent.log_error("Cannot create %s: %s", opname, str(e)) + self.parent.log_message("Exc: %s",traceback.format_exc()) + raise default_exc("Operation failed") + def _get_dav_lockdiscovery(self, uri): raise DAV_NotFound @@ -192,7 +231,7 @@ class openerp_dav_handler(dav_interface): if not node: if cr: cr.close() - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) else: fp = node.full_path() if fp and len(fp): @@ -255,7 +294,7 @@ class openerp_dav_handler(dav_interface): raise DAV_Error, 409 node = self.uri2object(cr, uid, pool, uri2) if not node: - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) try: if rrange: self.parent.log_error("Doc get_data cannot use range") @@ -268,7 +307,7 @@ class openerp_dav_handler(dav_interface): raise DAV_Forbidden except IndexError,e : self.parent.log_error("GET IndexError: %s", str(e)) - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) except Exception,e: import traceback self.parent.log_error("GET exception: %s",str(e)) @@ -288,7 +327,7 @@ class openerp_dav_handler(dav_interface): return COLLECTION node = self.uri2object(cr,uid,pool, uri2) if not node: - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) if node.type in ('collection','database'): return COLLECTION return OBJECT @@ -304,7 +343,7 @@ class openerp_dav_handler(dav_interface): node = self.uri2object(cr, uid, pool, uri2) if not node: cr.close() - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) cr.close() return node.displayname @@ -320,7 +359,7 @@ class openerp_dav_handler(dav_interface): node = self.uri2object(cr, uid, pool, uri2) if not node: cr.close() - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) result = node.content_length or 0 cr.close() return str(result) @@ -337,7 +376,7 @@ class openerp_dav_handler(dav_interface): node = self.uri2object(cr, uid, pool, uri2) if not node: cr.close() - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) result = node.get_etag(cr) cr.close() return str(result) @@ -352,7 +391,7 @@ class openerp_dav_handler(dav_interface): try: node = self.uri2object(cr, uid, pool, uri2) if not node: - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) if node.write_date: return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S')) else: @@ -369,7 +408,7 @@ class openerp_dav_handler(dav_interface): try: node = self.uri2object(cr, uid, pool, uri2) if not node: - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) if node.create_date: result = time.mktime(time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S')) else: @@ -387,7 +426,7 @@ class openerp_dav_handler(dav_interface): try: node = self.uri2object(cr, uid, pool, uri2) if not node: - raise DAV_NotFound(uri2) + raise DAV_NotFound2(uri2) result = str(node.mimetype) return result #raise DAV_NotFound, 'Could not find %s' % path @@ -398,6 +437,8 @@ class openerp_dav_handler(dav_interface): """ create a new collection """ self.parent.log_message('MKCOL: %s' % uri) uri = self.uri2local(uri)[1:] + if not uri: + raise DAV_Error(409, "Cannot create nameless collection") if uri[-1]=='/':uri=uri[:-1] parent = '/'.join(uri.split('/')[:-1]) parent = self.baseuri + parent @@ -430,22 +471,13 @@ class openerp_dav_handler(dav_interface): if not node: dir_node = self.uri2object(cr, uid, pool, uri2[:-1]) if not dir_node: + cr.close() raise DAV_NotFound('Parent folder not found') - try: - dir_node.create_child(cr, objname, data) - except Exception,e: - import traceback - self.parent.log_error("Cannot create %s: %s", objname, str(e)) - self.parent.log_message("Exc: %s",traceback.format_exc()) - raise DAV_Forbidden + + self._try_function(dir_node.create_child, (cr, objname, data), + "create %s" % objname, cr=cr) else: - try: - node.set_data(cr, data) - except Exception,e: - import traceback - self.parent.log_error("Cannot save %s: %s", objname, str(e)) - self.parent.log_message("Exc: %s",traceback.format_exc()) - raise DAV_Forbidden + self._try_function(node.set_data, (cr, data), "save %s" % objname, cr=cr) cr.commit() cr.close()