return helper
-def serialize_dashboard_exception(e):
+def serialize_dashboard_exception(e, include_http_status=False, task=None):
+ """
+ :type e: Exception
+ :param include_http_status: Used for Tasks, where the HTTP status code is not available.
+ """
from ..tools import ViewCache
- cherrypy.response.status = getattr(e, 'status', 400)
if isinstance(e, ViewCacheNoDataException):
return {'status': ViewCache.VALUE_NONE, 'value': None}
pass
component = getattr(e, 'component', None)
out['component'] = component if component else None
+ if include_http_status:
+ out['status'] = getattr(e, 'status', 500)
+ if task:
+ out['task'] = dict(name=task.name, metadata=task.metadata)
return out
except (ViewCacheNoDataException, DashboardException) as e:
logger.exception('dashboard_exception_handler')
cherrypy.response.headers['Content-Type'] = 'application/json'
+ cherrypy.response.status = getattr(e, 'status', 400)
return json.dumps(serialize_dashboard_exception(e)).encode('utf-8')
@cherrypy.expose
@cherrypy.tools.json_out()
- @Task('task_exceptions/task_exception', {}, 1.0,
+ @Task('task_exceptions/task_exception', {1: 2}, 1.0,
exception_handler=serialize_dashboard_exception)
@handle_rados_error('foo')
def task_exception(self):
self._get('/foo/task_exception')
self.assertStatus(400)
self.assertJsonBody(
- {'detail': '[errno -42] hi', 'code': "42", 'component': 'foo'}
+ {'detail': '[errno -42] hi', 'code': "42", 'component': 'foo',
+ 'task': {'name': 'task_exceptions/task_exception', 'metadata': {'1': 2}}}
)
self._get('/foo/wait_task_exception')
import threading
import time
from collections import defaultdict
+from functools import partial
+from ..services.exception import serialize_dashboard_exception
from ..tools import NotificationQueue, TaskManager, TaskExecutor
self.handle_ex = handle_ex
self._event = threading.Event()
- def _handle_exception(self, ex):
- return {'status': 409, 'detail': str(ex)}
-
def run(self, ns, timeout=None):
args = ['dummy arg']
kwargs = {'dummy': 'arg'}
- h_ex = self._handle_exception if self.handle_ex else None
+ h_ex = partial(serialize_dashboard_exception,
+ include_http_status=True) if self.handle_ex else None
if not self.is_async:
task = TaskManager.run(
ns, self.metadata(), self.task_op, args, kwargs,
self.assertEqual(fn_t[0]['progress'], 50)
self.assertFalse(fn_t[0]['success'])
self.assertIsNotNone(fn_t[0]['exception'])
- self.assertEqual(fn_t[0]['exception'],
- {"status": 409,
- "detail": "Task Unexpected Exception"})
+ self.assertEqual(fn_t[0]['exception'], {
+ 'component': None,
+ 'detail': 'Task Unexpected Exception',
+ 'status': 500,
+ 'task': {
+ 'metadata': {
+ 'fail': True,
+ 'handle_ex': True,
+ 'is_async': False,
+ 'op_seconds': 1,
+ 'progress': 50,
+ 'wait': False},
+ 'name': 'test15/task1'
+ }
+ })
if exception and self.ex_handler:
# pylint: disable=broad-except
try:
- ret_value = self.ex_handler(exception)
+ ret_value = self.ex_handler(exception, task=self)
except Exception as ex:
exception = ex
with self.lock: