Consider the following code:
try:
async with asyncvnc.connect(f'{ip}:{port}', username='user', password='password'):
return True
except PermissionError:
return True
return False
The interpreter says the return False statement is unreachable. Why?
I would assume that if connect() throws another runtime exception that isn't PermissionError than return False will be reached.
The return False statement is unreachable because if the asyncvnc.connect function throws an exception other than PermissionError, the exception will propagate up the call stack and cause the program to terminate. This means that the return False statement will never be executed.
In this code, the asyncvnc.connect function is being used inside a try block. If an exception occurs inside the try block, the code in the associated except block will be executed. In this case, if a PermissionError is raised, the return True statement will be executed, and the function will return immediately.
So, if any other exception other than PermissionError is raised, it will propagate up the call stack, and the program will terminate without executing the return False statement.
To avoid this issue, you can add another except block to catch any other exceptions that might be raised, and then return False in that block. This way, you will ensure that the function returns a value even if an exception occurs.
Here's the modified code:
try:
async with asyncvnc.connect(f'{ip}:{port}', username='user', password='password'):
return True
except PermissionError:
return True
except Exception as e:
print(f"An error occurred: {e}")
return False
Hope It will understandable
Related
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.
I want to ignore some exception in an library code (not my code)
as so:
try:
try: # not my code start
assert False
except:
print('not my code') # not my code end
except:
print('my code')
pass
So I will get into printing 'my code' at the end.
The results currently is:
'not my code' only.
You will get my code if the inner block, as a whole raises an exception. In your case, the inner block
try: # not my code start
assert False
except:
print('not my code') # not my code end
has handled it's exception, so, from the point of view of the outer try, it has completed successfully.
You could only cause the outer exception to be triggered by, raising an unhandled exception in the first try, or calling a function that raises an exception.
I need to return True Value after raise statement. Here I need to raise statement as well as it should return True value. If I use finally statement, it will not raise exception block and if I do not use finally then exception block will execute with raise statement and after that I will not able to use retcodecmd variable. Below My Code in python:
try:
something....
except ValueError:
self._retcodecmd = True
raise SomeException(something)
finally:
if self._retcodecmd is True:
return True
else:
return False
Returning and bubbling exceptions out of a function are mutually exclusive. It's nonsensical to exit a function by both raise and return, you have to choose.
The finally block here will force a return, undoing the exception you raised. If that's not what you want, you need to let the exception propagate without being overridden in the finally block and understand how to handle the exception appropriately in a caller.
def FancyDivide(list_of_numbers, index):
try:
try:
raise Exception("0")
finally:
denom = list_of_numbers[index]
for i in range(len(list_of_numbers)):
list_of_numbers[i] /= denom
except Exception, e:
print e
When function is called I got the following output.
FancyDivide([0, 2, 4], 0)
integer division or modulo by zero
In the try code an exception is raised. In finally also there is an exception .Why is it so that exception in the finally was caught not the exception in the try.
From the documentation -
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed.
(Emphasis mine)
As given, the exception - Exception("0") would have only been raised again after completing the finally block. But because an exception occured in the finally block, it was raised instead of the Exception("0") .
Let's say I have a program that runs continuously, waiting for order from a program with standard input. The method that keeps waiting for order is called "run" using while.
As you see, when run() gets certain order, they pass the order to certain function.
When I run the program, every time I give a command that can cause an error (say: Index error), it breaks and shut down (obviously)
I decided to try to catch the error with try/except
def a(order):
try:
<some algorithm>
return something
except Exception, error:
stderr.write(error)
stderr.flush()
def b(order):
try:
<some algorithm>
return something
except Exception, error:
stderr.write(error)
stderr.flush()
def run(order)
while stdin.notclosed:
try:
read stdin
if stdin==specific order :
x=a(stdin order)
else:
x=b(stdin order)
except Exception,error:
stderr.write(error)
stderr.flush()
run()
However, it seems the program that gives the order can't read the error. From my analyst, it seems the program that gives order only start reading stderr after the program that reads the order ends. However, due to try/catch, the program never ends. Is there anyway that to catch the error, write it, then end it. (The error can came from any function)
PS: Let's assume you can't modify or read the program that gives order. (This is competition, the reason I said this, is since that when I access the stderr, it's empty.)
Not sure if this does what you need, but you could re-raise the exception being handled by adding an emptyraisestatement at the end of theexceptblock as shown below. This will either cause the exception to be handled by the next higher-uptry/exceptblock, if there is one, or terminate the program if there isn't.
Example:
def a(order):
try:
<some algorithm>
return something
except Exception, error:
stderr.write(error)
stderr.flush()
raise # re-raise exception
def a(order):
try:
<some algorithm>
return something
except Exception, error:
import traceback
trace = traceback.format_exc()
return trace
def b(order):
try:
<some algorithm>
return something
except Exception, error:
import traceback
trace = traceback.format_exc()
return trace
def run(order)
while stdin.notclosed:
try:
read stdin
if stdin==specific order :
x=a(stdin order)
else:
x=b(stdin order)
#check if x == trace then sys.exit()
except Exception,error:
stderr.write(error)
stderr.flush()
run()