2016-12-14 125 views
1

我想爲Flask-restful API定義自定義錯誤處理。燒瓶 - 自定義錯誤處理

文檔here中的建議的方法是做到以下幾點:

errors = { 
    'UserAlreadyExistsError': { 
     'message': "A user with that username already exists.", 
     'status': 409, 
    }, 
    'ResourceDoesNotExist': { 
     'message': "A resource with that ID no longer exists.", 
     'status': 410, 
     'extra': "Any extra information you want.", 
    }, 
} 
app = Flask(__name__) 
api = flask_restful.Api(app, errors=errors) 

現在我發現這個格式非常有吸引力,但我需要一些時發生異常指定多個參數。例如,當遇到ResourceDoesNotExist時,我想指定什麼id不存在。

目前,我做了以下內容:

app = Flask(__name__) 
api = flask_restful.Api(app) 


class APIException(Exception): 
    def __init__(self, code, message): 
     self._code = code 
     self._message = message 

    @property 
    def code(self): 
     return self._code 

    @property 
    def message(self): 
     return self._message 

    def __str__(self): 
     return self.__class__.__name__ + ': ' + self.message 


class ResourceDoesNotExist(APIException): 
    """Custom exception when resource is not found.""" 
    def __init__(self, model_name, id): 
     message = 'Resource {} {} not found'.format(model_name.title(), id) 
     super(ResourceNotFound, self).__init__(404, message) 


class MyResource(Resource): 
    def get(self, id): 
     try: 
      model = MyModel.get(id) 
      if not model: 
       raise ResourceNotFound(MyModel.__name__, id) 
     except APIException as e: 
      abort(e.code, str(e)) 

當不存在MyResource將返回以下JSON的ID叫:

{'message': 'ResourceDoesNotExist: Resource MyModel 5 not found'} 

這工作得很好,但我d喜歡用於Flask-restful錯誤處理。

回答

2

根據the docs

瓶的RESTful會叫上在燒瓶的RESTful路由發生任何400或500錯誤在handle_error()函數,並獨自離開等航線。

您可以利用它來實現所需的功能。唯一的缺點是必須創建一個自定義Api。

class CustomApi(flask_restful.Api): 

    def handle_error(self, e): 
     flask_restful.abort(e.code, str(e)) 

如果你保持你定義的異常,發生異常時,你會得到相同的行爲

class MyResource(Resource): 
    def get(self, id): 
     try: 
      model = MyModel.get(id) 
      if not model: 
       raise ResourceNotFound(MyModel.__name__, id) 
     except APIException as e: 
      abort(e.code, str(e))