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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With