[#6530] Refactor error handling into context manager
- Also allows exc to propagate up so task will end in error state
Signed-off-by: Tim Van Steenburgh <tvansteenburgh@gmail.com>
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 54f006b..e0e9d6f 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -66,20 +66,31 @@
mount_label = fev.UnicodeString()
+class ImportErrorHandler(object):
+ def __init__(self, importer, project_name):
+ self.importer = importer
+ self.project_name = project_name
+
+ def __enter__(self):
+ pass
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ if exc_type:
+ g.post_event('import_tool_task_failed',
+ error=str(exc_val),
+ traceback=traceback.format_exc(),
+ importer_source=self.importer.source,
+ importer_tool_label=self.importer.tool_label,
+ project_name=self.project_name,
+ )
+
+
@task(notifications_disabled=True)
def import_tool(importer_name, project_name=None, mount_point=None, mount_label=None, **kw):
- try:
- importer = ToolImporter.by_name(importer_name)
+ importer = ToolImporter.by_name(importer_name)
+ with ImportErrorHandler(importer, project_name):
importer.import_tool(c.project, c.user, project_name=project_name,
mount_point=mount_point, mount_label=mount_label, **kw)
- except Exception as e:
- g.post_event('import_tool_task_failed',
- error=str(e),
- traceback=traceback.format_exc(),
- importer_source=importer.source,
- importer_tool_label=importer.tool_label,
- project_name=project_name,
- )
class ProjectExtractor(object):
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
index 5adaaa0..359632f 100644
--- a/ForgeImporters/forgeimporters/google/code.py
+++ b/ForgeImporters/forgeimporters/google/code.py
@@ -16,7 +16,6 @@
# under the License.
import urllib2
-import traceback
import formencode as fe
from formencode import validators as fev
@@ -38,7 +37,10 @@
from allura.lib import validators as v
from allura.lib.decorators import require_post, task
-from forgeimporters.base import ToolImporter
+from forgeimporters.base import (
+ ToolImporter,
+ ImportErrorHandler,
+ )
from forgeimporters.google import GoogleCodeProjectExtractor
REPO_APPS = {}
@@ -84,17 +86,9 @@
@task(notifications_disabled=True)
def import_tool(**kw):
- try:
- importer = GoogleRepoImporter()
+ importer = GoogleRepoImporter()
+ with ImportErrorHandler(importer, kw.get('project_name')):
importer.import_tool(c.project, c.user, **kw)
- except Exception as e:
- g.post_event('import_tool_task_failed',
- error=str(e),
- traceback=traceback.format_exc(),
- importer_source=importer.source,
- importer_tool_label=importer.tool_label,
- project_name=kw.get('project_name'),
- )
class GoogleRepoImportForm(fe.schema.Schema):
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index e5c8dc3..1535531 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -17,7 +17,6 @@
from collections import defaultdict
from datetime import datetime
-import traceback
from formencode import validators as fev
@@ -49,22 +48,15 @@
from forgeimporters.base import (
ToolImporter,
ToolImportForm,
+ ImportErrorHandler,
)
@task(notifications_disabled=True)
def import_tool(**kw):
- try:
- importer = GoogleCodeTrackerImporter()
+ importer = GoogleCodeTrackerImporter()
+ with ImportErrorHandler(importer, kw.get('project_name')):
importer.import_tool(c.project, c.user, **kw)
- except Exception as e:
- g.post_event('import_tool_task_failed',
- error=str(e),
- traceback=traceback.format_exc(),
- importer_source=importer.source,
- importer_tool_label=importer.tool_label,
- project_name=kw.get('project_name'),
- )
class GoogleCodeTrackerImportForm(ToolImportForm):
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index f6d443f..7de0625 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -20,7 +20,7 @@
from formencode import Invalid
import mock
from tg import expose
-from nose.tools import assert_equal
+from nose.tools import assert_equal, assert_raises
from alluratest.controller import TestController
@@ -66,7 +66,8 @@
importer.import_tool.side_effect = RuntimeError('my error')
ToolImporter.by_name.return_value = importer
- base.import_tool('importer_name', project_name='project_name')
+ assert_raises(RuntimeError, base.import_tool, 'importer_name',
+ project_name='project_name')
g.post_event.assert_called_once_with(
'import_tool_task_failed',
error=str(importer.import_tool.side_effect),
diff --git a/ForgeImporters/forgeimporters/trac/tickets.py b/ForgeImporters/forgeimporters/trac/tickets.py
index 7876b44..3063d71 100644
--- a/ForgeImporters/forgeimporters/trac/tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tickets.py
@@ -20,7 +20,6 @@
timedelta,
)
import json
-import traceback
from formencode import validators as fev
@@ -53,6 +52,7 @@
from forgeimporters.base import (
ToolImporter,
ToolImportForm,
+ ImportErrorHandler,
)
from forgetracker.tracker_main import ForgeTrackerApp
from forgetracker.scripts.import_tracker import import_tracker
@@ -60,17 +60,9 @@
@task(notifications_disabled=True)
def import_tool(**kw):
- try:
- importer = TracTicketImporter()
+ importer = TracTicketImporter()
+ with ImportErrorHandler(importer, kw.get('trac_url')):
importer.import_tool(c.project, c.user, **kw)
- except Exception as e:
- g.post_event('import_tool_task_failed',
- error=str(e),
- traceback=traceback.format_exc(),
- importer_source=importer.source,
- importer_tool_label=importer.tool_label,
- project_name=kw.get('trac_url'),
- )
class TracTicketImportForm(ToolImportForm):