Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
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
Exemple #4
0
 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()
Exemple #5
0
        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)
Exemple #6
0
 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>&ldquo;{}&rdquo;</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) 
Exemple #8
0
        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)
Exemple #9
0
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
Exemple #10
0
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
Exemple #12
0
    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
Exemple #13
0
 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)
Exemple #14
0
    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
Exemple #15
0
 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
Exemple #16
0
 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
Exemple #17
0
 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
Exemple #18
0
    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('&ldquo;{}&rdquo; 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('&ldquo;{}&rdquo; could not be deleted'.format(image.title))
        return jsonify({'next': url_for('Admin.edit_image',
                                        image_id=image_id)})
Exemple #20
0
    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
Exemple #21
0
    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
Exemple #23
0
 def _handle_exception(error):
     current_app.log_exception(error)
     return jsonify(status="failed", message=str(error)), 500
Exemple #24
0
    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
Exemple #25
0
        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)
Exemple #26
0
    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
Exemple #27
0
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())
Exemple #28
0
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})
Exemple #30
0
 def callback(result):
     exc = result.exception
     current_app.log_exception((type(exc), exc, exc.__traceback__))
Exemple #31
0
    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
Exemple #32
0
    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
Exemple #33
0
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())
Exemple #34
0
    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
Exemple #35
0
def default_error_handler(e):
    current_app.log_exception(e)
    return {"error": True, "message": str(e)}