def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: self.app.logger.exception("Internal Error") if code == 404: rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: data['message'] += '. You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join((rules[match] for match in close_matches)) + ' ?' resp = self.make_response(data, code) if code == 401: resp = unauthorized(resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ got_request_exception.send(current_app._get_current_object(), exception=e) if not hasattr(e, 'code') and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: # There's currently a bug in Python3 that disallows calling # logging.exception() when an exception hasn't actually be raised if sys.exc_info() == (None, None, None): current_app.logger.error("Internal Error") else: current_app.logger.exception("Internal Error") help_on_404 = current_app.config.get("ERROR_404_HELP", True) if code == 404 and help_on_404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in current_app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join(( rules[match] for match in close_matches) ) + ' ?' error_cls_name = type(e).__name__ if error_cls_name in self.errors: custom_data = self.errors.get(error_cls_name, {}) code = custom_data.get('status', 500) data.update(custom_data) resp = self.make_response(data, code) if code == 401: resp = self.unauthorized(resp) return resp
def test_handle_real_error(self): app = Flask(__name__) flask_restful.Api(app) app = app.test_client() resp = app.get("/foo") self.assertEquals(resp.status_code, 404) self.assertEquals(resp.data, dumps(error_data(404)))
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ got_request_exception.send(self.app, exception=e) if not hasattr(e, 'code') and self.app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: exc = exc_type(exc_value) exc.__traceback__ = tb raise exc else: raise e code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: # There's currently a bug in Python3 that disallows calling # logging.exception() when an exception hasn't actually be raised if sys.exc_info() == (None, None, None): self.app.logger.error("Internal Error") else: self.app.logger.exception("Internal Error") if code == 404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join((rules[match] for match in close_matches)) + ' ?' resp = self.make_response(data, code) if code == 401: resp = unauthorized( resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ got_request_exception.send(self.app, exception=e) if not hasattr(e, 'code') and self.app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: exc = exc_type(exc_value) exc.__traceback__ = tb raise exc else: raise e code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: # There's currently a bug in Python3 that disallows calling # logging.exception() when an exception hasn't actually be raised if sys.exc_info() == (None, None, None): self.app.logger.error("Internal Error") else: self.app.logger.exception("Internal Error") if code == 404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join((rules[match] for match in close_matches)) + ' ?' resp = self.make_response(data, code) if code == 401: resp = unauthorized(resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ got_request_exception.send(self.app, exception=e) if not hasattr(e, "code") and self.app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e code = getattr(e, "code", 500) data = getattr(e, "data", error_data(code)) if code >= 500: # There's currently a bug in Python3 that disallows calling # logging.exception() when an exception hasn't actually be raised if sys.exc_info() == (None, None, None): self.app.logger.error("Internal Error") else: self.app.logger.exception("Internal Error") if code == 404 and ("message" not in data or data["message"] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub("(<.*>)", "", rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data["message"] += ( "You have requested this URI [" + request.path + "] but did you mean " + " or ".join((rules[match] for match in close_matches)) + " ?" ) resp = self.make_response(data, code) if code == 401: resp = self.unauthorized(resp) return resp
def abort(http_status_code, details=None): """ Return an error response, with the given 'http_status_code' and a JSON body. Optionally, supplemental 'details' may be provided, which will be included with the response body. This function provides the same {'status', 'message'} response body as Flask-Restful, but also allows an optional 'details' field to be added. """ data = error_data(http_status_code) if details: data['details'] = details restful_abort(http_status_code, **data)
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ got_request_exception.send(self, exception=e) code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: self.app.logger.exception("Internal Error") if code == 404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join((rules[match] for match in close_matches)) + ' ?' resp = self.make_response(data, code) if code == 401: resp = unauthorized( resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: self.app.logger.exception("Internal Error") resp = self.make_response(data, code) if code == 401: resp = unauthorized(resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ got_request_exception.send(self, exception=e) code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) if code >= 500: self.app.logger.exception("Internal Error") if code == 404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join((rules[match] for match in close_matches)) + ' ?' resp = self.make_response(data, code) if code == 401: resp = unauthorized(resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def handle_error(self, e): """Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body. :param e: the raised Exception object :type e: Exception """ code = getattr(e, "code", 500) data = getattr(e, "data", error_data(code)) if code >= 500: self.app.logger.exception("Internal Error") if code == 404: rules = dict([(re.sub("(<.*>)", "", rule.rule), rule.rule) for rule in self.app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data["message"] += ( "You have requested this URI [" + request.path + "] but did you mean " + " or ".join((rules[match] for match in close_matches)) + " ?" ) resp = self.make_response(data, code) if code == 401: resp = unauthorized(resp, self.app.config.get("HTTP_BASIC_AUTH_REALM", "flask-restful")) return resp
def test_error_data(self): self.assertEquals(error_data(400), { 'status': 400, 'message': 'Bad Request', })
def handle_error(self, e): got_request_exception.send(current_app._get_current_object(), exception=e) if not hasattr(e, 'code') and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) headers = {} if code >= 500: if sys.exc_info() == (None, None, None): current_app.logger.error("Internal Error") else: current_app.logger.exception("Internal Error") help_on_404 = current_app.config.get("ERROR_404_HELP", True) if code == 404 and help_on_404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in current_app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join(( rules[match] for match in close_matches) ) + ' ?' if code == 405: headers['Allow'] = e.valid_methods error_cls_name = type(e).__name__ if error_cls_name in self.errors: custom_data = self.errors.get(error_cls_name, {}) code = custom_data.get('status', 500) data.update(custom_data) if code == 406 and self.default_mediatype is None: supported_mediatypes = list(self.representations.keys()) fallback_mediatype = supported_mediatypes[0] if supported_mediatypes else "text/plain" resp = self.make_response( data, code, headers, fallback_mediatype=fallback_mediatype, ) else: if code == 400 and current_app.config.get('CHANGE_400_TO_200', self.default_change_400_to_200): code = 200 resp = self.make_response(data, code, headers) if code == 401: resp = self.unauthorized(resp) return resp
def handle_error(self, e): got_request_exception.send(current_app._get_current_object(), exception=e) if not hasattr(e, 'code') and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e code = getattr(e, 'code', 500) data = getattr(e, 'data', error_data(code)) headers = {} if code >= 500: if sys.exc_info() == (None, None, None): current_app.logger.error("Internal Error") else: current_app.logger.exception("Internal Error") help_on_404 = current_app.config.get("ERROR_404_HELP", True) if code == 404 and help_on_404 and ('message' not in data or data['message'] == HTTP_STATUS_CODES[404]): rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule) for rule in current_app.url_map.iter_rules()]) close_matches = difflib.get_close_matches(request.path, rules.keys()) if close_matches: # If we already have a message, add punctuation and continue it. if "message" in data: data["message"] += ". " else: data["message"] = "" data['message'] += 'You have requested this URI [' + request.path + \ '] but did you mean ' + \ ' or '.join(( rules[match] for match in close_matches) ) + ' ?' if code == 405: headers['Allow'] = e.valid_methods error_cls_name = type(e).__name__ if error_cls_name in self.errors: custom_data = self.errors.get(error_cls_name, {}) code = custom_data.get('status', 500) data.update(custom_data) if code == 406 and self.default_mediatype is None: supported_mediatypes = list(self.representations.keys()) fallback_mediatype = supported_mediatypes[ 0] if supported_mediatypes else "text/plain" resp = self.make_response( data, code, headers, fallback_mediatype=fallback_mediatype, ) else: if code == 400 and current_app.config.get( 'CHANGE_400_TO_200', self.default_change_400_to_200): code = 200 resp = self.make_response(data, code, headers) if code == 401: resp = self.unauthorized(resp) return resp