]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | # -*- coding: utf-8 -*- |
11fdf7f2 TL |
2 | |
3 | import json | |
9f95a23c | 4 | import logging |
f67539c2 | 5 | from contextlib import contextmanager |
11fdf7f2 | 6 | |
20effc67 | 7 | import cephfs |
11fdf7f2 | 8 | import cherrypy |
11fdf7f2 | 9 | import rados |
f67539c2 TL |
10 | import rbd |
11 | from orchestrator import OrchestratorError | |
11fdf7f2 | 12 | |
f67539c2 | 13 | from ..exceptions import DashboardException, ViewCacheNoDataException |
20effc67 | 14 | from ..rest_client import RequestException |
11fdf7f2 | 15 | from ..services.ceph_service import SendCommandError |
9f95a23c TL |
16 | |
17 | logger = logging.getLogger('exception') | |
18 | ||
19 | ||
11fdf7f2 TL |
20 | def serialize_dashboard_exception(e, include_http_status=False, task=None): |
21 | """ | |
22 | :type e: Exception | |
23 | :param include_http_status: Used for Tasks, where the HTTP status code is not available. | |
24 | """ | |
25 | from ..tools import ViewCache | |
26 | if isinstance(e, ViewCacheNoDataException): | |
27 | return {'status': ViewCache.VALUE_NONE, 'value': None} | |
28 | ||
29 | out = dict(detail=str(e)) | |
30 | try: | |
31 | out['code'] = e.code | |
32 | except AttributeError: | |
33 | pass | |
34 | component = getattr(e, 'component', None) | |
35 | out['component'] = component if component else None | |
36 | if include_http_status: | |
37 | out['status'] = getattr(e, 'status', 500) | |
38 | if task: | |
9f95a23c | 39 | out['task'] = dict(name=task.name, metadata=task.metadata) # type: ignore |
11fdf7f2 TL |
40 | return out |
41 | ||
42 | ||
f67539c2 | 43 | # pylint: disable=broad-except |
11fdf7f2 TL |
44 | def dashboard_exception_handler(handler, *args, **kwargs): |
45 | try: | |
46 | with handle_rados_error(component=None): # make the None controller the fallback. | |
47 | return handler(*args, **kwargs) | |
48 | # Don't catch cherrypy.* Exceptions. | |
f67539c2 | 49 | except (ViewCacheNoDataException, DashboardException) as error: |
9f95a23c | 50 | logger.exception('Dashboard Exception') |
11fdf7f2 | 51 | cherrypy.response.headers['Content-Type'] = 'application/json' |
f67539c2 TL |
52 | cherrypy.response.status = getattr(error, 'status', 400) |
53 | return json.dumps(serialize_dashboard_exception(error)).encode('utf-8') | |
54 | except Exception as error: | |
55 | logger.exception('Internal Server Error') | |
56 | raise error | |
11fdf7f2 TL |
57 | |
58 | ||
20effc67 TL |
59 | @contextmanager |
60 | def handle_cephfs_error(): | |
61 | try: | |
62 | yield | |
63 | except cephfs.OSError as e: | |
64 | raise DashboardException(e, component='cephfs') from e | |
65 | ||
66 | ||
11fdf7f2 TL |
67 | @contextmanager |
68 | def handle_rbd_error(): | |
69 | try: | |
70 | yield | |
71 | except rbd.OSError as e: | |
72 | raise DashboardException(e, component='rbd') | |
73 | except rbd.Error as e: | |
74 | raise DashboardException(e, component='rbd', code=e.__class__.__name__) | |
75 | ||
76 | ||
77 | @contextmanager | |
78 | def handle_rados_error(component): | |
79 | try: | |
80 | yield | |
81 | except rados.OSError as e: | |
82 | raise DashboardException(e, component=component) | |
83 | except rados.Error as e: | |
84 | raise DashboardException(e, component=component, code=e.__class__.__name__) | |
85 | ||
86 | ||
87 | @contextmanager | |
88 | def handle_send_command_error(component): | |
89 | try: | |
90 | yield | |
91 | except SendCommandError as e: | |
92 | raise DashboardException(e, component=component) | |
9f95a23c TL |
93 | |
94 | ||
95 | @contextmanager | |
96 | def handle_orchestrator_error(component): | |
97 | try: | |
98 | yield | |
99 | except OrchestratorError as e: | |
100 | raise DashboardException(e, component=component) | |
20effc67 TL |
101 | |
102 | ||
103 | @contextmanager | |
104 | def handle_request_error(component): | |
105 | try: | |
106 | yield | |
107 | except RequestException as e: | |
108 | if e.content: | |
109 | content = json.loads(e.content) | |
110 | content_message = content.get('message') | |
111 | if content_message: | |
112 | raise DashboardException( | |
113 | msg=content_message, component=component) | |
114 | raise DashboardException(e=e, component=component) |