]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/services/exception.py
1 # -*- coding: utf-8 -*-
2 from __future__
import absolute_import
5 from contextlib
import contextmanager
11 from orchestrator
import OrchestratorError
15 from ..services
.ceph_service
import SendCommandError
16 from ..exceptions
import ViewCacheNoDataException
, DashboardException
17 from ..tools
import wraps
20 logger
= logging
.getLogger('exception')
24 # Monkey-patch a __call__ method into @contextmanager to make
25 # it compatible to Python 3
27 # pylint: disable=no-name-in-module,ungrouped-imports
28 from contextlib
import GeneratorContextManager
30 def init(self
, *args
):
34 self
.func
, self
.args
, self
.kwargs
= args
39 if hasattr(self
, 'func'):
40 self
.gen
= self
.func(*self
.args
, **self
.kwargs
)
42 return self
.gen
.next()
44 raise RuntimeError("generator didn't yield")
48 def wrapper(*args
, **kwargs
):
50 return f(*args
, **kwargs
)
54 GeneratorContextManager
.__init
__ = init
55 GeneratorContextManager
.__enter
__ = enter
56 GeneratorContextManager
.__call
__ = call
58 # pylint: disable=function-redefined
59 def contextmanager(func
): # noqa: F811
62 def helper(*args
, **kwds
):
63 return GeneratorContextManager(func
, args
, kwds
)
68 def serialize_dashboard_exception(e
, include_http_status
=False, task
=None):
71 :param include_http_status: Used for Tasks, where the HTTP status code is not available.
73 from ..tools
import ViewCache
74 if isinstance(e
, ViewCacheNoDataException
):
75 return {'status': ViewCache
.VALUE_NONE
, 'value': None}
77 out
= dict(detail
=str(e
))
80 except AttributeError:
82 component
= getattr(e
, 'component', None)
83 out
['component'] = component
if component
else None
84 if include_http_status
:
85 out
['status'] = getattr(e
, 'status', 500)
87 out
['task'] = dict(name
=task
.name
, metadata
=task
.metadata
) # type: ignore
91 def dashboard_exception_handler(handler
, *args
, **kwargs
):
93 with
handle_rados_error(component
=None): # make the None controller the fallback.
94 return handler(*args
, **kwargs
)
95 # Don't catch cherrypy.* Exceptions.
96 except (ViewCacheNoDataException
, DashboardException
) as e
:
97 logger
.exception('Dashboard Exception')
98 cherrypy
.response
.headers
['Content-Type'] = 'application/json'
99 cherrypy
.response
.status
= getattr(e
, 'status', 400)
100 return json
.dumps(serialize_dashboard_exception(e
)).encode('utf-8')
104 def handle_rbd_error():
107 except rbd
.OSError as e
:
108 raise DashboardException(e
, component
='rbd')
109 except rbd
.Error
as e
:
110 raise DashboardException(e
, component
='rbd', code
=e
.__class
__.__name
__)
114 def handle_rados_error(component
):
117 except rados
.OSError as e
:
118 raise DashboardException(e
, component
=component
)
119 except rados
.Error
as e
:
120 raise DashboardException(e
, component
=component
, code
=e
.__class
__.__name
__)
124 def handle_send_command_error(component
):
127 except SendCommandError
as e
:
128 raise DashboardException(e
, component
=component
)
132 def handle_orchestrator_error(component
):
135 except OrchestratorError
as e
:
136 raise DashboardException(e
, component
=component
)