Python / GAE Web Request Error Handling

I am developing an application on Google App Engine using Python.

I have a handler that can return various outputs (html and json at the moment), I am testing obvious errors in the system based on invalid parameters sent to the request handler.

However, what I am doing seems dirty (see below):

class FeedHandler(webapp.RequestHandler): def get(self): app = self.request.get("id") name = self.request.get("name") output_type = self.request.get("output", default_value = "html") pretty = self.request.get("pretty", default_value = "") application = model.Application.GetByKey(app) if application is None: if output_type == "json": self.response.out.write(simplejson.dumps({ "errorCode" : "Application not found."})) self.set_status(404) return category = model.FeedCategory.GetByKey(application, name) if category is None: if output_type == "json": self.response.out.write(simplejson.dumps({ "errorCode" : "Category not found."})) self.set_status(404) return 

I specifically handle cases for each type of output, as well as for "assert".

I am fond of suggestions, examples, and examples of how to clean it (I know that it will be a nightmare to try and save what I am doing).

I play with the idea of ​​having and raising custom exceptions and having a decorator that will automatically work out how to display error messages - I think this is a good idea, but I would like to get some feedback and suggestions based on how people did it in the past.

+4
source share
2 answers

There are several convenient methods here. The first is me. error (code). By default, this method simply sets the status code and clears the output buffer, but you can override it to display custom error pages depending on the error result.

The second method is self. handle__exception (exception, debug_mode). This method is called by the webapp framework if any of your get / post / etc methods returns an unhandled exception. By default, it raises self.error (500) and raises an exception (and also prints it on output if debugging mode is enabled). You can override this method to handle exceptions as you like. Here is an example that allows you to set exceptions for different statuses:

 class StatusCodeException(Exception): def __init__(self, code): self.status_code = code class RedirectException(StatusCodeException): def __init__(self, location, status=302): super(RedirectException, self).__init__(status) self.location = location class ForbiddenException(StatusCodeException): def __init__(self): super(ForbiddenException, self).__init__(403) class ExtendedHandler(webapp.RequestHandler): def handle_exception(self, exception, debug_mode): if isinstance(exception, RedirectException): self.redirect(exception.location) else: self.error(exception.status_code) 
+9
source

At a minimum, you should reorganize the duplicate code, for example:

 if application is None: if output_type == "json": self.response.out.write(simplejson.dumps({ "errorCode" : "Application not found."})) self.set_status(404) return 

in the helper method:

 def _Mayerr(self, result, msg): if result is None: if output_type == 'json': self.response.out.write(simplejson.dumps( {"errorCode": msg}) self.set_status(404) return True 

and name it, for example. as:

 if self._Mayerr(application, "Application not found."): return 

In addition, custom exceptions (and wrapping all of your handlers with a decorator that catches exceptions and gives the correct error messages) is a great architecture, although it is more invasive (requires more rework of your code) than simple refactoring, which I just mentioned above , additional investments right now can be useful in preventing repeated and collimated error handling throughout your application code level! -)

0
source

All Articles