1 """
2 A place for exception-handling logic
3 """
4
5 import logging
6
7 import flask
8 from werkzeug.exceptions import HTTPException, NotFound, GatewayTimeout
9 from coprs.exceptions import CoprHttpException
10 from coprs.views.misc import (
11 generic_error,
12 access_restricted,
13 bad_request_handler,
14 conflict_request_handler,
15 page_not_found,
16 )
17
18 LOG = logging.getLogger(__name__)
19
20
22 """
23 Determine what error handler should be used for this request
24 See http://flask.pocoo.org/docs/1.0/blueprints/#error-handlers
25 """
26 if flask.request.path.startswith('/api_3/'):
27 return APIErrorHandler()
28 return UIErrorHandler()
29
30
32 """
33 Do not use this class for handling errors. It is only a parent class for
34 the actual error-handler classes.
35 """
36
38 """
39 Return a flask response suitable for the current situation (e.g. reder
40 HTML page for UI failures, send JSON back to API client, etc).
41
42 This method is expected to be implemented in descendants of this class.
43 """
44 raise NotImplementedError
45
46 - def code(self, error):
47 """
48 Return status code for a given exception
49 """
50 return getattr(error, "code", 500)
51
53 """
54 Return an error message for a given exception. We want to obtain messages
55 differently for `CoprHttpException`, `HTTPException`, or others.
56 """
57 if isinstance(error, HTTPException):
58 return error.description
59 return str(error)
60
61
63 """
64 Handle exceptions raised from the web user interface
65 """
66
85
86
88 """
89 Handle exceptions raised from API (v3)
90 """
91
93 code = self.code(error)
94 message = self.message(error)
95
96
97
98
99
100 errors = {
101 NotFound: "Such API endpoint doesn't exist",
102 GatewayTimeout: "The API request timeouted",
103 }
104 if error.__class__ in errors:
105 message = errors[error.__class__]
106
107
108
109
110
111
112
113 if not any([isinstance(error, CoprHttpException),
114 isinstance(error, HTTPException)]):
115 message = ("Request wasn't successful, "
116 "there is probably a bug in the API code.")
117 LOG.exception("Admin-only exception")
118 return self.respond(message, code)
119
121 """
122 Return JSON response suitable for API clients
123 """
124 response = flask.jsonify(error=message)
125 response.status_code = code
126 return response
127