feature 8029 change RO to python3. Using vim plugins
[osm/RO.git] / RO / osm_ro / http_tools / errors.py
1 # -*- coding: utf-8 -*-
2 import logging
3 from functools import wraps
4
5 import bottle
6 import yaml
7
8 Bad_Request = 400
9 Unauthorized = 401
10 Not_Found = 404
11 Forbidden = 403
12 Method_Not_Allowed = 405
13 Not_Acceptable = 406
14 Request_Timeout = 408
15 Conflict = 409
16 Service_Unavailable = 503
17 Internal_Server_Error = 500
18
19
20 class HttpMappedError(Exception):
21 """Base class for a new hierarchy that translate HTTP error codes
22 to python exceptions
23
24 This class accepts an extra argument ``http_code`` (integer
25 representing HTTP error codes).
26 """
27
28 def __init__(self, message, http_code=Internal_Server_Error):
29 Exception.__init__(self, message)
30 self.http_code = http_code
31
32
33 class ErrorHandler(object):
34 """Defines a default strategy for handling HttpMappedError.
35
36 This class implements a wrapper (can also be used as decorator), that
37 watches out for different exceptions and log them accordingly.
38
39 Arguments:
40 logger(logging.Logger): logger object to be used to report errors
41 """
42 def __init__(self, logger=None):
43 self.logger = logger or logging.getLogger('openmano.http')
44
45 def __call__(self, function):
46 @wraps(function)
47 def _wraped(*args, **kwargs):
48 try:
49 return function(*args, **kwargs)
50 except bottle.HTTPError:
51 raise
52 except HttpMappedError as ex:
53 self.logger.error(
54 "%s error %s",
55 function.__name__, ex.http_code, exc_info=True)
56 bottle.abort(ex.http_code, str(ex))
57 except yaml.YAMLError as ex:
58 self.logger.error(
59 "YAML error while trying to serialize/unserialize fields",
60 exc_info=True)
61 bottle.abort(Bad_Request, type(ex).__name__ + ": " + str(ex))
62 except Exception as ex:
63 self.logger.error("Unexpected exception: ", exc_info=True)
64 bottle.abort(Internal_Server_Error,
65 type(ex).__name__ + ": " + str(ex))
66
67 return _wraped