Frage

I am using tornado to create a rest handler.. Here i have some common exceptions like InvalidRequest, InvalidToken etc. So i wanted to know how i can create a sort of super exception handler for these and handle the rest in the same function itself.. Part of the example code

class RestRegisterHandler(RestHandler):
@gen.coroutine
def post(self):
    self.raw_data = None
    try:
        yield self.validate_user()
        self.raw_data = json_decode(self.request.body)
        logger.debug(self.raw_data)
        model_object = self.model(self.raw_data)
        model_object.validate()
        logger.debug("Inseting to database")
        yield model_object.insert(self.db)
    except InvalidRequest:
        self.write_error(404, 'Invalid request')
    except InvalidToken:
        self.write_error(404, 'Token Validation Failed')
    except ModelValidationError as error:
        logger.error("Unknown Validation error: '{0}'".format(error))
        raise utils.errors.ValidationError(400, error_messages=error.messages)
    except DuplicateKeyError:
        logger.debug("User already exists")
        self.write_error(404, 'User already exists')
    except Exception as e:
        logger.error(e)
        self.write_error(404, 'Invalid request')
    else:
        logger.debug("db saved")
        self.write("Registered succesfully")
        return

Something like

class RestHandler():
  def super_exception():
    except InvalidToken:
        print()
    except InvalidRequest:
        print()
    # the rest of exceptions should be handled by post function
War es hilfreich?

Lösung

Something like this?

class RestHandler(object):
    # "default" exception handling in the super class
    def handle_exception(self, e):
        logger.error('Default error handling caught a "%s"' % e)

class RestRegisterHandler(RestHandler):
    # "specific" exception handling in the child class
    def handle_exception(self, e):
        # Just an idea, you can implement this in different ways
        WRITE_ERROR             = (InvalidRequest, InvalidToken, DuplicateKeyError)
        WRITE_ERROR_WITH_LOGGER = (Exception,)
        RAISE_VALIDATION_ERROR  = (ModelValidationError,)

        if e in WRITE_ERROR:
            self.write_error(404, str(e))
        elif e in WRITE_ERROR_WITH_LOGGER:
            logger.error(e)
            self.write_error(404, str(e))
        elif e in RAISE_VALIDATION_ERROR:
            logger.error("Unknown Validation error: '{0}'".format(e))
            raise utils.errors.ValidationError(400, error_messages=e.messages)
        else:
            # if couldn't be handled here, fallback to the default implementation
            super(RestHandler, self).handle_exception(e)        


    @gen.coroutine
    def post(self):
        self.raw_data = None
        try:
            yield self.validate_user()
            self.raw_data = json_decode(self.request.body)
            logger.debug(self.raw_data)
            model_object = self.model(self.raw_data)
            model_object.validate()
            logger.debug("Inseting to database")
            yield model_object.insert(self.db)

        except Exception as e:
            self.handle_exception(e)

        else:
            logger.debug("db saved")
            self.write("Registered succesfully")
            return

Andere Tipps

The general solution for this is to override RequestHandler.write_error (and don't call write_error yourself, just let the errors escape the handler function). write_error will get an exc_info keyword argument that lets you see the exception that caused the request to fail.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top