Team Ai
Apppublic

Underground-Digital/Workflow-Engine

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
external_api.py119 linesDownload Raw Back to libs
1import re2import sys3 4from flask import current_app, got_request_exception5from flask_restful import Api, http_status_message6from werkzeug.datastructures import Headers7from werkzeug.exceptions import HTTPException8 9from core.errors.error import AppInvokeQuotaExceededError10 11 12class ExternalApi(Api):13    def handle_error(self, e):14        """Error handler for the API transforms a raised exception into a Flask15        response, with the appropriate HTTP status code and body.16 17        :param e: the raised Exception object18        :type e: Exception19 20        """21        got_request_exception.send(current_app, exception=e)22 23        headers = Headers()24        if isinstance(e, HTTPException):25            if e.response is not None:26                resp = e.get_response()27                return resp28 29            status_code = e.code30            default_data = {31                "code": re.sub(r"(?<!^)(?=[A-Z])", "_", type(e).__name__).lower(),32                "message": getattr(e, "description", http_status_message(status_code)),33                "status": status_code,34            }35 36            if (37                default_data["message"]38                and default_data["message"] == "Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)"39            ):40                default_data["message"] = "Invalid JSON payload received or JSON payload is empty."41 42            headers = e.get_response().headers43        elif isinstance(e, ValueError):44            status_code = 40045            default_data = {46                "code": "invalid_param",47                "message": str(e),48                "status": status_code,49            }50        elif isinstance(e, AppInvokeQuotaExceededError):51            status_code = 42952            default_data = {53                "code": "too_many_requests",54                "message": str(e),55                "status": status_code,56            }57        else:58            status_code = 50059            default_data = {60                "message": http_status_message(status_code),61            }62 63        # Werkzeug exceptions generate a content-length header which is added64        # to the response in addition to the actual content-length header65        # https://github.com/flask-restful/flask-restful/issues/53466        remove_headers = ("Content-Length",)67 68        for header in remove_headers:69            headers.pop(header, None)70 71        data = getattr(e, "data", default_data)72 73        error_cls_name = type(e).__name__74        if error_cls_name in self.errors:75            custom_data = self.errors.get(error_cls_name, {})76            custom_data = custom_data.copy()77            status_code = custom_data.get("status", 500)78 79            if "message" in custom_data:80                custom_data["message"] = custom_data["message"].format(81                    message=str(e.description if hasattr(e, "description") else e)82                )83            data.update(custom_data)84 85        # record the exception in the logs when we have a server error of status code: 50086        if status_code and status_code >= 500:87            exc_info = sys.exc_info()88            if exc_info[1] is None:89                exc_info = None90            current_app.log_exception(exc_info)91 92        if status_code == 406 and self.default_mediatype is None:93            # if we are handling NotAcceptable (406), make sure that94            # make_response uses a representation we support as the95            # default mediatype (so that make_response doesn't throw96            # another NotAcceptable error).97            supported_mediatypes = list(self.representations.keys())  # only supported application/json98            fallback_mediatype = supported_mediatypes[0] if supported_mediatypes else "text/plain"99            data = {"code": "not_acceptable", "message": data.get("message")}100            resp = self.make_response(data, status_code, headers, fallback_mediatype=fallback_mediatype)101        elif status_code == 400:102            if isinstance(data.get("message"), dict):103                param_key, param_value = list(data.get("message").items())[0]104                data = {"code": "invalid_param", "message": param_value, "params": param_key}105            else:106                if "code" not in data:107                    data["code"] = "unknown"108 109            resp = self.make_response(data, status_code, headers)110        else:111            if "code" not in data:112                data["code"] = "unknown"113 114            resp = self.make_response(data, status_code, headers)115 116        if status_code == 401:117            resp = self.unauthorized(resp)118        return resp119