def try_call(func, self, *args, **kw): """Call function, catch and dispatch any resulting exception.""" # turbogears.database import here to avoid circular imports from turbogears.database import restart_transaction try: return func(self, *args, **kw) except Exception, e: if isinstance(e, cherrypy.HTTPRedirect) or \ call_on_stack("dispatch_error", {"tg_source": func, "tg_exception": e}, 4): raise else: exc_type, exc_value, exc_trace = sys.exc_info() remove_keys(kw, ("tg_source", "tg_errors", "tg_exceptions")) if 'tg_format' in cherrypy.request.params: kw['tg_format'] = 'json' if getattr(cherrypy.request, "in_transaction", None): restart_transaction(1) try: output = dispatch_error(self, func, None, e, *args, **kw) except NoApplicableMethods: raise exc_type, exc_value, exc_trace else: del exc_trace return output
def _execute_func(func, template, format, content_type, mapping, fragment, args, kw): """Call controller method and process it's output.""" if config.get("tg.strict_parameters", False): tg_util.remove_keys(kw, ["tg_random", "tg_format"] + config.get("tg.ignore_parameters", [])) else: # get special parameters used by upstream decorators like paginate try: tg_kw = dict([(k, v) for k, v in kw.items() if k in func._tg_args]) except AttributeError: tg_kw = {} # remove excessive parameters args, kw = tg_util.adapt_call(func, args, kw) # add special parameters again kw.update(tg_kw) if config.get('server.environment', 'development') == 'development': # Only output this in development mode: If it's a field storage object, # this means big memory usage, and we don't want that in production log.debug("Calling %s with *(%s), **(%s)", func, args, kw) output = errorhandling.try_call(func, *args, **kw) assert isinstance(output, (basestring, dict, list, types.GeneratorType)), \ "Method %s.%s() returned unexpected output. Output should " \ "be of type basestring, dict, list or generator." % ( args[0].__class__.__name__, func.__name__) if isinstance(output, dict): template = output.pop("tg_template", template) format = output.pop("tg_format", format) if template and template.startswith("."): template = func.__module__[:func.__module__.rfind('.')]+template return _process_output(output, template, format, content_type, mapping, fragment)
def _execute_func(func, template, format, content_type, mapping, fragment, args, kw): """Call controller method and process it's output.""" if config.get("tg.strict_parameters", False): tg_util.remove_keys(kw, ["tg_random", "tg_format"] + config.get("tg.ignore_parameters", [])) else: # get special parameters used by upstream decorators like paginate try: tg_kw = dict([(k, v) for k, v in kw.items() if k in func._tg_args]) except AttributeError: tg_kw = {} # remove excessive parameters args, kw = tg_util.adapt_call(func, args, kw) # add special parameters again kw.update(tg_kw) if config.get('server.environment', 'development') == 'development': # Only output this in development mode: If it's a field storage object, # this means big memory usage, and we don't want that in production log.debug("Calling %s with *(%s), **(%s)", func, args, kw) output = errorhandling.try_call(func, *args, **kw) assert isinstance(output, (basestring, dict, list, types.GeneratorType)), \ "Method %s.%s() returned unexpected output. Output should " \ "be of type basestring, dict, list or generator." % ( args[0].__class__.__name__, func.__name__) if isinstance(output, dict): template = output.pop("tg_template", template) format = output.pop("tg_format", format) if template and template.startswith("."): template = func.__module__[:func.__module__.rfind('.')] + template return _process_output(output, template, format, content_type, mapping, fragment)
def try_call(func, self, *args, **kw): """Call function, catch and dispatch any resulting exception.""" # turbogears.database import here to avoid circular imports from turbogears.database import _use_sa try: return func(self, *args, **kw) except Exception, e: if isinstance(e, cherrypy.HTTPRedirect) or \ call_on_stack("dispatch_error", {"tg_source":func, "tg_exception":e}, 4): raise elif _use_sa() and getattr(cherrypy.request, "in_transaction", None): # We're in a transaction and using SA, let # database.run_with_transaction handle and dispatch # the exception raise else: exc_type, exc_value, exc_trace = sys.exc_info() remove_keys(kw, ("tg_source", "tg_errors", "tg_exceptions")) try: output = dispatch_error(self, func, None, e, *args, **kw) except NoApplicableMethods: raise exc_type, exc_value, exc_trace else: del exc_trace return output
def dispatch_exception(exception,args, kw): # errorhandling import here to avoid circular imports from turbogears.errorhandling import dispatch_error # Keep in mind func is not the real func but _expose real_func, accept, allow_json, controller = args[:4] args = args[4:] exc_type, exc_value, exc_trace = sys.exc_info() remove_keys(kw, ("tg_source", "tg_errors", "tg_exceptions")) try: output = dispatch_error( controller, real_func, None, exception, *args, **kw) except dispatch.NoApplicableMethods: raise exc_type, exc_value, exc_trace else: del exc_trace return output
def dispatch_exception(exception, args, kw): # errorhandling import here to avoid circular imports from turbogears.errorhandling import dispatch_error # Keep in mind func is not the real func but _expose real_func, accept, allow_json, controller = args[:4] args = args[4:] exc_type, exc_value, exc_trace = sys.exc_info() remove_keys(kw, ("tg_source", "tg_errors", "tg_exceptions")) try: output = dispatch_error(controller, real_func, None, exception, *args, **kw) except dispatch.NoApplicableMethods: raise exc_type, exc_value, exc_trace else: del exc_trace return output
def run_with_errors(errors, func, self, *args, **kw): """Branch execution depending on presence of errors.""" if errors: if hasattr(self, "validation_error"): import warnings warnings.warn( "Use decorator error_handler() on per-method base " "rather than defining a validation_error() method.", DeprecationWarning, 2) return self.validation_error(func.__name__, kw, errors) else: remove_keys(kw, ("tg_source", "tg_errors", "tg_exceptions")) try: return dispatch_error(self, func, errors, None, *args, **kw) except NoApplicableMethods: raise NotImplementedError("Method %s.%s() has no applicable " "error handler." % (self.__class__.__name__, func.__name__)) else: return func(self, *args, **kw)
def run_with_errors(errors, func, self, *args, **kw): """Branch execution depending on presence of errors.""" if errors: if hasattr(self, "validation_error"): import warnings warnings.warn( "Use decorator error_handler() on per-method base " "rather than defining a validation_error() method.", DeprecationWarning, 2) return self.validation_error(func.__name__, kw, errors) else: remove_keys(kw, ("tg_source", "tg_errors", "tg_exceptions")) if 'tg_format' in cherrypy.request.params: kw['tg_format'] = 'json' try: return dispatch_error(self, func, errors, None, *args, **kw) except NoApplicableMethods: raise NotImplementedError( "Method %s.%s() has no applicable " "error handler." % (self.__class__.__name__, func.__name__)) else: return func(self, *args, **kw)
def _execute_func(func, template, format, content_type, mapping, fragment, args, kw): """Call controller method and process it's output.""" if config.get("tg.strict_parameters", False): tg_util.remove_keys(kw, ["tg_random", "tg_format"]) else: args, kw = tg_util.adapt_call(func, args, kw) if config.get('server.environment', 'development') == 'development': # Only output this in development mode: If it's a field storage object, # this means big memory usage, and we don't want that in production log.debug("Calling %s with *(%s), **(%s)", func, args, kw) output = errorhandling.try_call(func, *args, **kw) if isinstance(output, list): return output assert isinstance(output, basestring) or isinstance(output, dict) \ or isinstance(output, types.GeneratorType), \ "Method %s.%s() returned unexpected output. Output should " \ "be of type basestring, dict or generator." % ( args[0].__class__.__name__, func.__name__) if isinstance(output, dict): template = output.pop("tg_template", template) format= output.pop("tg_format", format) if template and template.startswith("."): template = func.__module__[:func.__module__.rfind('.')]+template return _process_output(output, template, format, content_type, mapping, fragment)
def test_remove_keys(): assert util.remove_keys(dict(x=1, y=2, z=3), 'xz') == dict(y=2)