May be a little confused on how flask handles errors. Working on adding error handling to a DB backend. I essentially have a worker script, a router, and error handling script.
The error handling is pretty basic. I have a separate module with the following classes. They inherit from exception so there is not much added to them
class EmptyQueryError(Exception):
pass
class BadURLError(Exception):
pass
My main route method is as follows, and calls a method which takes care of post process/etc.
def queryJobData(projectId, jobId):
try:
dbv.jobData(projectId, jobId)
except EmptyQueryError as e:
abort(400, "An unexpected Exception Occurred: {}".format(e))
except Exception as e:
abort(400, "An unexpected Exception Occurred: {}".format(e))
Lastly, the main driver function is contained in the dbv object from about. The flow of this works properly, as for when I pass in valued project and job ids, the query is successful and it returns a document as I aim to. However, when I purposely insert errors to get an exception to raise, that's where issues occur. Here is the handler function:
def jobData(self, projectId, jobId):
try:
print("[Querying the job data]")
if (request.method == "GET"):
qData = [x for x in self.collection.find({"projectId": projectId, "jobId": jobId})]
# input(qData)
if (len(qData) == 0):
raise EmptyQueryError("EmptyQueryError: The url you attempted to query did not return any data")
pp.data = qData
unrolled_data = pp.unrollData()
df = pd.DataFrame(unrolled_data)
pps = PostProcessSummary(df)
table_test = pps.pivot_summary()
return dumps(table_test)
except Exception as e:
print(e)
finally:
pass
I purposely did not import the "request" module so it raises an error. I can see it gets caught by "jobData":
However, it never enters one of the exception blocks in "queryJobData", where the handle "jobData" is called.
To say the least this has thrown me a for a loop. Almost all other pieces of software I've built would handle this exception accordingly. (ie it follows the pattern where if one exception is raised elsewhere, it should be handled by the parent calling the child generating the exception). First time using Flask so I imagine I'm missing something obvious I can't find in documentation.
edit: The exception in jobData() gets caught and it exists back into queryJobData() as if nothing happens. For instance in this block it goes directly to the return and not to handle the raised exception
try:
dbv_ret = dbv.jobData(projectId, jobId)
return dbv_ret
except TypeError:
abort(400, "TypeError Occurred")
except EmptyQueryError:
print("[ARE WE HERE?!]")
abort(404, "Empty Query")
except BadURLError:
abort(404, "Bad URL")
except Exception as e:
abort(404, "An unexptec exception has occurred: {}".format(e))
You a catching all exceptions in you function, so anything that happens inside the try/except block will be caught inside your except block, and then your finally block will be executed.
If you want to pass the EmptyQueryError and BadURLError exceptions to the calling function, raise it outside the try/except block. Or, if you want, re-raise it inside your except block
class EmptyQueryError(Exception):
pass
class BadURLError(Exception):
pass
def jobData():
try:
print("[Querying the job data]")
# this will be caught by the except block
raise EmptyQueryError("EmptyQueryError: The url you attempted to query did not return any data")
except Exception as e:
# catching all exceptions. Including the ones you are raising.
# if you don't re-raise the exception here, no error will be passed
print("Wow, exception")
print(e)
finally:
print("I'm in finally block ;)")
# not returning anything
pass
if __name__ == "__main__":
try:
returned_value = jobData()
# will print None
print(returned_value)
except EmptyQueryError as query_err:
# will never be caught
print("Got a EmptyQueryError")
except BadURLError as url_err:
# will never be caught
print("Got a BadURLError")
The sequence of prints will be:
[Querying the job data]
Wow, exception
EmptyQueryError: The url you attempted to query did not return any data
I'm in finally block ;)
None
You can do something like:
def jobData(data):
if len(data) == 0:
raise EmptyQueryError("EmptyQueryError: The url you attempted to query did not return any data")
try:
# do your thing here
pass
except Exception as e:
print(e)
finally:
print("I'm in finally block ;)")
# not returning anything
pass
Now the EmptyQueryError will be caught by the calling function.