1import traceback 2 3from bottle import HTTPResponse 4 5from conans.errors import ConanException 6from conans.util.log import logger 7 8 9class ReturnHandlerPlugin(object): 10 """ The ReturnHandlerPlugin plugin unify REST return and exception management """ 11 12 name = 'ReturnHandlerPlugin' 13 api = 2 14 15 def __init__(self, exception_mapping): 16 self.exception_mapping = exception_mapping 17 18 def setup(self, app): 19 """ Make sure that other installed plugins don't affect the same 20 keyword argument. """ 21 for other in app.plugins: 22 if not isinstance(other, ReturnHandlerPlugin): 23 continue 24 25 def apply(self, callback, _): 26 """ Apply plugin """ 27 def wrapper(*args, **kwargs): 28 """ Capture possible exceptions to manage the return """ 29 try: 30 # The encoding from browsers is utf-8, so we assume it 31 for key, value in kwargs.items(): 32 if isinstance(value, str): 33 kwargs[key] = value 34 return callback(*args, **kwargs) # kwargs has :xxx variables from url 35 except HTTPResponse: 36 raise 37 except ConanException as excep: 38 return get_response_from_exception(excep, self.exception_mapping) 39 except Exception as e: 40 logger.error(e) 41 logger.error(traceback.print_exc()) 42 return get_response_from_exception(e, self.exception_mapping) 43 44 return wrapper 45 46 47def get_response_from_exception(excep, exception_mapping): 48 status = exception_mapping.get(excep.__class__, None) 49 if status is None: 50 status = 500 51 ret = HTTPResponse(status=status, body=str(excep)) 52 ret.add_header("Content-Type", "text/plain") 53 return ret 54