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 Exception e: the raised Exception object ''' got_request_exception.send(current_app._get_current_object(), exception=e) headers = Headers() if e.__class__ in self.error_handlers: handler = self.error_handlers[e.__class__] result = handler(e) default_data, code, headers = unpack(result, 500) elif isinstance(e, HTTPException): code = e.code default_data = { 'message': getattr(e, 'description', HTTP_STATUS_CODES.get(code, '')) } headers = e.get_response().headers elif self._default_error_handler: result = self._default_error_handler(e) default_data, code, headers = unpack(result, 500) else: code = 500 default_data = { 'message': HTTP_STATUS_CODES.get(code, str(e)), } default_data['message'] = default_data.get('message', str(e)) data = getattr(e, 'data', default_data) fallback_mediatype = None if code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) elif code == 404 and current_app.config.get("ERROR_404_HELP", True): data['message'] = self._help_on_404(data.get('message', None)) elif code == 406 and self.default_mediatype is None: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). supported_mediatypes = list(self.representations.keys()) fallback_mediatype = supported_mediatypes[0] if supported_mediatypes else "text/plain" # Remove blacklisted headers for header in HEADERS_BLACKLIST: headers.pop(header, None) resp = self.make_response(data, code, headers, fallback_mediatype=fallback_mediatype) if code == 401: resp = self.unauthorized(resp) return resp
def _create_error_out(api_exception): got_request_exception.send(current_app._get_current_object(), exception=api_exception) headers = Headers() if isinstance(api_exception, HTTPException): status_code = api_exception.code msg = getattr(api_exception, 'description', http_status_message(status_code)) headers = api_exception.get_response().headers else: status_code = 500 msg = http_status_message(status_code) remove_headers = ('Content-Length', ) for header in remove_headers: headers.pop(header, None) if status_code and status_code >= 500: exc_info = sys.exc_info() current_app.log_exception(exc_info) error_out = { 'error': { 'message': msg, 'name': type(api_exception).__name__ }, 'status': status_code, 'success': False } return error_out, status_code, headers
def handle_error(self): """log and return response""" if self.code and self.code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) return self.get_response()
def handle_werkzeug_http_error(error): exc_info = sys.exc_info() current_app.log_exception(exc_info=exc_info) for func in self.uncaught_exception_handlers: func(error) return self._create_json_error_response( message=messages.internal_server_error, http_status_code=500)
def coerce(self, value, type): try: if type is bool: if isinstance(value, (str, unicode)): return value.lower() not in ('False', 'false', 'no', '0') return bool(value) return type(value) except Exception as e: current_app.log_exception(e) abort(400)
def edit_contact(_id): """edit/update contact or link to social media profile """ tmpl_args = {'page_title':'edit contact info'} try: contact_info = Contact.query.get_or_404(_id) except: current_app.log_exception(sys.exc_info()) return redirect(url_for('Admin.contact')) if request.method == 'GET': form = ContactForm(obj=contact_info) if request.method == 'POST': form = ContactForm(request.form) if len(contact_info.email): tmpl_args['type'] = 'email' else: tmpl_args['type'] = 'profile' filename = contact_info.icon_filename tmpl_args['icon_filename'] = filename if form.validate_on_submit(): db.session.add(contact_info) update_model_from_form(contact_info, form) icon_file = request.files.get('icon') if icon_file: icon_filename = save_icon(icon_file) if icon_filename: contact_info.icon_filename = icon_filename if tmpl_args['type'] == 'email': name = contact_info.email if tmpl_args['type'] == 'profile': name = contact_info.name flash('<strong>“{}”</strong> has been updated'.format(name)) db.session.commit() msg = '[{}] updated'.format(name) current_app.logger.info(msg) return redirect(url_for('Admin.edit_contact', _id=_id)) if len(form.errors): flash_form_errors(form.errors) return render_template('admin_edit_contact.html', form=form, **tmpl_args)
def handle_generic_error(error): exc_info = sys.exc_info() current_app.log_exception(exc_info=exc_info) for func in self.uncaught_exception_handlers: func(error) if current_app.debug: raise error else: return self._create_json_error_response( message=messages.internal_server_error, http_status_code=500)
def handle_exception(e): if request.accept_mimetypes.best == 'application/json': # exceptions are logged by flask when not handled or when re-raised. # as here we construct a json error response, we have to log the exception our-self. current_app.log_exception(sys.exc_info()) # TODO: verify that sentry is able to collect these exceptions! server_error = InternalServerError(original_exception=e) return handle_internal_server_error(server_error) else: # If PROPAGATE_EXCEPTIONS=True (default value in debug mode), # this will produce a debug page with the full backtrace. # Otherwise, an InternalServerError will be produced by flask. raise e
def validate_object_dict(obj_dict: Dict[str, Any]) -> bool: """Validate a dict representation of a Gramps object vs. its schema.""" try: obj_cls = getattr(gramps.gen.lib, obj_dict["_class"]) except (KeyError, AttributeError, TypeError): return False schema = obj_cls.get_schema() obj_dict_fixed = {k: v for k, v in obj_dict.items() if k != "complete"} try: jsonschema.validate(obj_dict_fixed, schema) except jsonschema.exceptions.ValidationError as exc: current_app.log_exception(exc) return False return True
def _make_error_response(self, code, default_data, e, headers): ''' Creates and returns a Flask response with given HTTP status code, body and headers based on given arguments :param code: HTTP status code :param default_data: Response body :param e: Original exception that led to this error response :param headers: Response headers ''' include_message_in_response = current_app.config.get( "ERROR_INCLUDE_MESSAGE", True) if include_message_in_response: default_data['message'] = default_data.get('message', str(e)) else: default_data.pop('message', None) data = getattr(e, 'data', default_data) fallback_mediatype = None if code >= HTTPStatus.INTERNAL_SERVER_ERROR: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) elif code == HTTPStatus.NOT_FOUND and current_app.config.get("ERROR_404_HELP", True) \ and include_message_in_response: data['message'] = self._help_on_404(data.get('message', None)) elif code == HTTPStatus.NOT_ACCEPTABLE and self.default_mediatype is None: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). supported_mediatypes = list(self.representations.keys()) fallback_mediatype = supported_mediatypes[ 0] if supported_mediatypes else "text/plain" # Remove blacklisted headers for header in HEADERS_BLACKLIST: headers.pop(header, None) resp = self.make_response(data, code, headers, fallback_mediatype=fallback_mediatype) if code == HTTPStatus.UNAUTHORIZED: resp = self.unauthorized(resp) return resp
def verify(self, hash: str, password: str): try: self._hasher.verify(hash, password) return True # handle verify mismatch, when password is invalid except argon2.exceptions.VerifyMismatchError: return False # handle other exceptions, logging it into application except ( argon2.exceptions.InvalidHash, argon2.exceptions.Argon2Error, ) as exc: app.log_exception(exc) return False
def execute_task(): try: # Websockets don't automatically log anything so we use # this decorator to keep track of what's executing. current_app.logger.info('Socket.io - %s', message) f(*args, **kwargs) except Exception as err: # Send HTTP errors to the client if status code available. if hasattr(err, 'code'): error = {'name': e.name, 'message': e.message, 'description': e.description, 'code': e.code} emit(message, error) else: current_app.log_exception(err)
def fix_error_router(self, original_handler, e): "Hmm!" exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None if (exc_info): if logger: logger.info(str(e)) else: current_app.log_exception(exc_info) else: if logger: logger.info(str(e)) else: current_app.logger.error(str(e)) return e
def handle_exception(self, exc_type, exc_value, exc_tb): if isinstance(exc_value, HTTPException): resp = jsonify(error={"code": exc_value.code, "name": exc_value.name, "description": exc_value.description}) resp.status_code = exc_value.code else: current_app.log_exception((exc_type, exc_value, exc_tb)) error = { "code": 500, "name": "Internal Server Error", "description": "Enable debug mode for more information", } if current_app.debug: error["traceback"] = traceback.format_exc().split("\n") error["name"] = exc_type.__name__ error["description"] = str(exc_value) resp = jsonify(error=error) resp.status_code = 500 return resp
def handle_exception(self, exc_type, exc_value, exc_tb): if isinstance(exc_value, HTTPException): resp = jsonify(error={ 'code': exc_value.code, 'name': exc_value.name, 'description': exc_value.description, }) resp.status_code = exc_value.code else: current_app.log_exception((exc_type, exc_value, exc_tb)) error = { 'code': 500, 'name': 'Internal Server Error', 'description': 'Enable debug mode for more information', } if current_app.debug: error['traceback'] = traceback.format_exc().split('\n') error['name'] = exc_type.__name__ error['description'] = str(exc_value) resp = jsonify(error=error) resp.status_code = 500 return resp
def handle_exception(self, exc_type, exc_value, exc_tb): if isinstance(exc_value, HTTPException): resp = jsonify(error={ 'code': exc_value.code, 'name': exc_value.name, 'description': exc_value.get_description(request), }) resp.status_code = exc_value.code else: current_app.log_exception((exc_type, exc_value, exc_tb)) error = { 'code': 500, 'name': 'Internal Server Error', 'description': 'Enable debug mode for more information', } if current_app.debug: error['traceback'] = traceback.format_exc().split('\n') error['name'] = exc_type.__name__ error['description'] = str(exc_value) resp = jsonify(error=error) resp.status_code = 500 return resp
def generator(): ctx = _request_ctx_stack.top if ctx is None: raise RuntimeError('Attempted to stream with context but ' 'there was no context in the first place to keep around.') with ctx: # Dummy sentinel. Has to be inside the context block or we're # not actually keeping the context around. yield None # The try/finally is here so that if someone passes a WSGI level # iterator in we're still running the cleanup logic. Generators # don't need that because they are closed on their destruction # automatically. try: for item in gen: yield item except Exception as e: exc_type, exc_value, tb = sys.exc_info() current_app.log_exception((exc_type, exc_value, tb)) finally: if hasattr(gen, 'close'): gen.close()
def delete_image(image_id): if not request.is_xhr: raise NotFound try: image = Image.query.get(image_id) except: current_app.log_exception(sys.exc_info()) flash('The image could not be deleted') return jsonify({'next': url_for('Admin.edit_image', image_id=image_id)}) if not image: current_app.log_exception(sys.exc_info()) flash('The image could not be deleted') return jsonify({'next': url_for('Admin.edit_image', image_id=image_id)}) series_id = image.series.id try: db.session.delete(image) img_root = current_app.config['STATIC_IMAGE_ROOT'] thumb_root = current_app.config['STATIC_THUMBNAIL_ROOT'] img_path = Path(img_root, image.filename) thumb_path = Path(thumb_root, image.filename) img_path.unlink() thumb_path.unlink() flash('“{}” has been permanently deleted'. format(image.title)) db.session.commit() msg = '[{}] deleted from [{}]'.format(image.title, image.series.title) current_app.logger.info(msg) return jsonify({'next': url_for('Admin.edit_series', _id=str(series_id))}) except: current_app.log_exception(sys.exc_info()) flash('“{}” could not be deleted'.format(image.title)) return jsonify({'next': url_for('Admin.edit_image', image_id=image_id)})
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 Exception e: the raised Exception object ''' got_request_exception.send(current_app._get_current_object(), exception=e) include_message_in_response = current_app.config.get( "ERROR_INCLUDE_MESSAGE", True) default_data = {} headers = Headers() if e.__class__ in self.error_handlers: handler = self.error_handlers[e.__class__] result = handler(e) default_data, code, headers = unpack( result, HTTPStatus.INTERNAL_SERVER_ERROR) elif isinstance(e, HTTPException): code = HTTPStatus(e.code) if include_message_in_response: default_data = { 'message': getattr(e, 'description', code.phrase) } headers = e.get_response().headers elif self._default_error_handler: result = self._default_error_handler(e) default_data, code, headers = unpack( result, HTTPStatus.INTERNAL_SERVER_ERROR) else: code = HTTPStatus.INTERNAL_SERVER_ERROR if include_message_in_response: default_data = { 'message': code.phrase, } if include_message_in_response: default_data['message'] = default_data.get('message', str(e)) data = getattr(e, 'data', default_data) fallback_mediatype = None if code >= HTTPStatus.INTERNAL_SERVER_ERROR: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) elif code == HTTPStatus.NOT_FOUND and current_app.config.get("ERROR_404_HELP", True) \ and include_message_in_response: data['message'] = self._help_on_404(data.get('message', None)) elif code == HTTPStatus.NOT_ACCEPTABLE and self.default_mediatype is None: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). supported_mediatypes = list(self.representations.keys()) fallback_mediatype = supported_mediatypes[ 0] if supported_mediatypes else "text/plain" # Remove blacklisted headers for header in HEADERS_BLACKLIST: headers.pop(header, None) resp = self.make_response(data, code, headers, fallback_mediatype=fallback_mediatype) if code == HTTPStatus.UNAUTHORIZED: resp = self.unauthorized(resp) 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 isinstance(e, HTTPException) and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e headers = Headers() if isinstance(e, HTTPException): if e.response is not None: # If HTTPException is initialized with a response, then return e.get_response(). # This prevents specified error response from being overridden. # eg. HTTPException(response=Response("Hello World")) resp = e.get_response() return resp code = e.code default_data = { 'message': getattr(e, 'description', http_status_message(code)) } headers = e.get_response().headers else: code = 500 default_data = { 'message': http_status_message(code), } # Werkzeug exceptions generate a content-length header which is added # to the response in addition to the actual content-length header # https://github.com/flask-restful/flask-restful/issues/534 remove_headers = ('Content-Length', ) for header in remove_headers: headers.pop(header, None) data = getattr(e, 'data', default_data) if code and code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) 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: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). 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: resp = self.make_response(data, code, headers) if code == 401: resp = self.unauthorized(resp) 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 isinstance(e, HTTPException) and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e headers = Headers() if isinstance(e, HTTPException): if e.response is not None: # If HTTPException is initialized with a response, then return e.get_response(). # This prevents specified error response from being overridden. # eg. HTTPException(response=Response("Hello World")) resp = e.get_response() return resp code = e.code default_data = { 'message': getattr(e, 'description', http_status_message(code)) } headers = e.get_response().headers else: code = 500 default_data = { 'message': http_status_message(code), } # Werkzeug exceptions generate a content-length header which is added # to the response in addition to the actual content-length header # https://github.com/flask-restful/flask-restful/issues/534 remove_headers = ('Content-Length',) for header in remove_headers: headers.pop(header, None) data = getattr(e, 'data', default_data) if code and code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) 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: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). 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: resp = self.make_response(data, code, headers) if code == 401: resp = self.unauthorized(resp) return resp
def _handle_exception(error): current_app.log_exception(error) return jsonify(status="failed", message=str(error)), 500
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 isinstance(e, HTTPException) and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e headers = Headers() if isinstance(e, HTTPException): code = e.code default_data = { 'message': getattr(e, 'description', http_status_message(code)) } headers = e.get_response().headers else: code = 500 default_data = { 'message': http_status_message(code), } # Werkzeug exceptions generate a content-length header which is added # to the response in addition to the actual content-length header # https://github.com/flask-restful/flask-restful/issues/534 remove_headers = ('Content-Length',) for header in remove_headers: headers.pop(header, None) data = getattr(e, 'data', default_data) if code and code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) help_on_404 = current_app.config.get("ERROR_404_HELP", True) if code == 404 and help_on_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"] = data["message"].rstrip('.') + '. ' 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) if code == 406 and self.default_mediatype is None: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). 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: resp = self.make_response(data, code, headers) if code == 401: resp = self.unauthorized(resp) return resp
def run_unhandled_exception_handlers(exception): exc_info = sys.exc_info() current_app.log_exception(exc_info=exc_info) for func in self.uncaught_exception_handlers: func(exception)
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 isinstance(e, HTTPException) and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e if isinstance(e, HTTPException): code = e.code default_data = { 'message': getattr(e, 'description', http_status_message(code)) } else: code = 500 default_data = { 'message': http_status_message(code), } data = getattr(e, 'data', default_data) headers = {} if code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) help_on_404 = current_app.config.get("ERROR_404_HELP", True) if code == 404 and help_on_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"] = data["message"].rstrip('.') + '. ' 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: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). 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: resp = self.make_response(data, code, headers) if code == 401: resp = self.unauthorized(resp) return resp
def handle_generic_exception(e): "Return a REST-formated error response instead of the standard 500 html template" current_app.log_exception(sys.exc_info()) return REST.marsh_error(InternalError())
def uncaught_error_handler(e): import sys import backend_common.constants.http_code as http_code from flask import jsonify, current_app current_app.log_exception(sys.exc_info()) return jsonify({'errcode': http_code.INTERNAL_SERVER_ERROR, 'errmsg': e.__class__.__name__})
def handle(self): import sys from flask import jsonify, current_app if not current_app.testing: current_app.log_exception(sys.exc_info()) return jsonify({'errcode': self.errcode, 'errmsg': self.errmsg})
def callback(result): exc = result.exception current_app.log_exception((type(exc), exc, exc.__traceback__))
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 Exception e: the raised Exception object ''' got_request_exception.send(current_app._get_current_object(), exception=e) include_message_in_response = current_app.config.get("ERROR_INCLUDE_MESSAGE", True) default_data = {} headers = Headers() for typecheck, handler in six.iteritems(self._own_and_child_error_handlers): if isinstance(e, typecheck): result = handler(e) default_data, code, headers = unpack(result, HTTPStatus.INTERNAL_SERVER_ERROR) break else: if isinstance(e, HTTPException): code = HTTPStatus(e.code) if include_message_in_response: default_data = { 'message': getattr(e, 'description', code.phrase) } headers = e.get_response().headers elif self._default_error_handler: result = self._default_error_handler(e) default_data, code, headers = unpack(result, HTTPStatus.INTERNAL_SERVER_ERROR) else: code = HTTPStatus.INTERNAL_SERVER_ERROR if include_message_in_response: default_data = { 'message': code.phrase, } if include_message_in_response: default_data['message'] = default_data.get('message', str(e)) data = getattr(e, 'data', default_data) fallback_mediatype = None if code >= HTTPStatus.INTERNAL_SERVER_ERROR: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) elif code == HTTPStatus.NOT_FOUND and current_app.config.get("ERROR_404_HELP", True) \ and include_message_in_response: data['message'] = self._help_on_404(data.get('message', None)) elif code == HTTPStatus.NOT_ACCEPTABLE and self.default_mediatype is None: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). supported_mediatypes = list(self.representations.keys()) fallback_mediatype = supported_mediatypes[0] if supported_mediatypes else "text/plain" # Remove blacklisted headers for header in HEADERS_BLACKLIST: headers.pop(header, None) resp = self.make_response(data, code, headers, fallback_mediatype=fallback_mediatype) if code == HTTPStatus.UNAUTHORIZED: resp = self.unauthorized(resp) 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) is_http_exception = isinstance(e, HTTPException) if not is_http_exception and current_app.propagate_exceptions: exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: # pragma: no cover raise e if is_http_exception: code = e.code default_data = { 'message': getattr(e, 'description', http_status_message(code)) } else: code = 500 default_data = { 'message': http_status_message(code), } data = getattr(e, 'data', default_data) headers = {'Access-Control-Allow-Origin': '*'} if code >= 500: exc_info = sys.exc_info() if exc_info[1] is None: # pragma: no cover exc_info = None current_app.log_exception(exc_info) help_on_404 = current_app.config.get("ERROR_404_HELP", True) if code == 404 and help_on_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"] = data["message"].rstrip('.') + '. ' else: # pragma: no cover 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 enhanced_data = copy.deepcopy(envelope) enhanced_data.update(copy.deepcopy(error_meta)) enhanced_data["meta"]["error_type"] = e.__class__.__name__ enhanced_data["meta"]["code"] = code enhanced_data["meta"]["error_message"] = data['message'] resp = self.make_response(enhanced_data, code, headers) if code == 401: # pragma: no cover resp = self.unauthorized(resp) 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 Exception e: the raised Exception object """ got_request_exception.send(current_app._get_current_object(), exception=e) # When propagate_exceptions is set, do not return the exception to the # client if a handler is configured for the exception. if (not isinstance(e, HTTPException) and current_app.propagate_exceptions and not isinstance(e, tuple(self.error_handlers.keys()))): exc_type, exc_value, tb = sys.exc_info() if exc_value is e: raise else: raise e include_message_in_response = current_app.config.get( "ERROR_INCLUDE_MESSAGE", True) default_data = {} headers = Headers() for typecheck, handler in six.iteritems( self._own_and_child_error_handlers): if isinstance(e, typecheck): result = handler(e) default_data, code, headers = unpack( result, HTTPStatus.INTERNAL_SERVER_ERROR) break else: if isinstance(e, HTTPException): code = HTTPStatus(e.code) if include_message_in_response: default_data = { "message": getattr(e, "description", code.phrase) } headers = e.get_response().headers elif self._default_error_handler: result = self._default_error_handler(e) default_data, code, headers = unpack( result, HTTPStatus.INTERNAL_SERVER_ERROR) else: code = HTTPStatus.INTERNAL_SERVER_ERROR if include_message_in_response: default_data = { "message": code.phrase, } if include_message_in_response: default_data["message"] = default_data.get("message", str(e)) data = getattr(e, "data", default_data) fallback_mediatype = None if code >= HTTPStatus.INTERNAL_SERVER_ERROR: exc_info = sys.exc_info() if exc_info[1] is None: exc_info = None current_app.log_exception(exc_info) elif (code == HTTPStatus.NOT_FOUND and current_app.config.get("ERROR_404_HELP", True) and include_message_in_response): data["message"] = self._help_on_404(data.get("message", None)) elif code == HTTPStatus.NOT_ACCEPTABLE and self.default_mediatype is None: # if we are handling NotAcceptable (406), make sure that # make_response uses a representation we support as the # default mediatype (so that make_response doesn't throw # another NotAcceptable error). supported_mediatypes = list(self.representations.keys()) fallback_mediatype = (supported_mediatypes[0] if supported_mediatypes else "text/plain") # Remove blacklisted headers for header in HEADERS_BLACKLIST: headers.pop(header, None) resp = self.make_response(data, code, headers, fallback_mediatype=fallback_mediatype) if code == HTTPStatus.UNAUTHORIZED: resp = self.unauthorized(resp) return resp
def default_error_handler(e): current_app.log_exception(e) return {"error": True, "message": str(e)}