Is it a good pattern to raise exceptions in a python decorator?
Context : I have Flask routes defined for different API endpoints and each endpoint calls a controller class with certain parameters (uid, project_id, etc.).
@app.route('/sample/route', methods=['POST'])
@require_json_payload
@require_fields({
'pid',
'params'
})
def route_handler(arg1, arg2):
#input filtering
...
try:
proj_cntr.sample_method(
pid = pid,
... = ...
)
except ProjCntrException:
#handle error
#response generation
...
The controller (proj_cntr) is responsible for determining, say, if the given PID is valid, wether the given user is allowed to perform the action, and other business logic validation.
I noticed that I am c/pasting a lot of code like this in different controllers:
if not project_object:
sys_logger.info('...')
raise ProjCntrException('PID %d does not exist' % pid)
Putting these checks (validations) in decorators seems like the best thing to do. But I am not sure which error handling pattern is best practice should the validation not pass.
1) Should I create specific custom exceptions (InvalidProjException, PermissionsException, etc.) for each decorator to raise?
Concerns : The catch block of the caller method will look bloated. Also, is it good to make the assumption that the caller knows what exceptions the decorators of the callee raise?
2) The decorator passes an extra error argument to the method and the method decides what exception to raise. This way the caller method is aware what exception type to expect and handle.
Concerns : Approach seems a little over-engineered and messy.
Sorry for the verbose question. Any thoughts/ideas are greatly appreciated.
I ended up using decorators and throwing specific exceptions within them. For example:
The @validate_pid
decorator raises InvalidPidException()
which are caught in the except block of any consumer that calls the decorated method.
Advantages so far:
Disadvantages so far:
Option 1 : It seems logical to create a specific Exception
for your decorator because this will help the user know which exception is raised, if any, and why. The type of exception should, of course, appear in the decorator docstring for the caller to be able to know what to expect. This way you're not making the assumption the user knows what exception is raised but that he has read the doc - which is more likely assumption. However if the method is called often the caller will have to handle it every time. That's part of the deal when using a library, an API or someone else's code.
Option 2 : It does not belong to the user to determine which exception is going to be raised. The user should be aware of it via the documentation, for example. It is messy and counter intuitive in term of API design.
Thinking about your question it made me think about the way Java works, especially if you use an IDE, when calling a method you will be warned - by the IDE and via the typing mechanism - that you should try/catch
a given type of exception.
But in your case wouldn't be possible to raise a proper HTTPException
with a specific message ?
上一篇: 返回统一的初始化参考是否有效?