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.
Related
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
I have a try/except block with multiple except blocks. I want to be able to execute a piece of code only if any of the exceptions are raised. Kind of like the finally statement, but finally execute regardless of if an exception was raised or not. Do I just have to add that code to each except block?
You can do your own type checking in the exception handler to deal with type-specific and general code.
def it_will_end_in_tears():
raise ValueError("bad value")
try:
val = it_will_end_in_tears()
except (TypeError, ValueError) as e:
if isinstance(e, TypeError):
print("type error stuff")
elif isinstance(e, ValueError):
print("value error stuff")
print("common stuff")
finally:
print("finally")
Instead of copy+pasting the code into each except block, i would declare a boolean execute_code = False and set it to True in each of the except blocks. After the whole try/except, add if execute_code:, then implement the code to execute if an exception occurred once inside the if block.
Consider the following code:
def f(x):
if x < 10:
return Exception("error")
else:
raise Exception("error2")
if __name__ == "__main__":
try:
f(5) # f(20)
except Exception:
print str(Exception)
Is there any difference?
When should I use return Exception and When should I use raise?
raise and return are two inherently different keywords.
raise, commonly known as throw in other languages, produces an error in the current level of the call-stack. You can catch a raised error by covering the area where the error might be raised in a try and handling that error in an except.
try:
if something_bad:
raise generate_exception()
except CertainException, e:
do_something_to_handle_exception(e)
return on the other hand, returns a value to where the function was called from, so returning an exception usually is not the functionality you are looking for in a situation like this, since the exception itself is not the thing triggering the except it is instead the raiseing of the exception that triggers it.
I have a function that reads a CSV, checks the values in the rows, and if everything is okay, it writes the rows to a new CSV file. I have a few validation functions I'm calling within my main function to check the value and format of the rows.
I'm trying to implement my main function in a way so that when I call the other validation functions and something doesn't check out, I skip writing that row entirely.
#main function
for row in reader:
try:
row['amnt'] = divisible_by_5(row['amnt'])
row['issue_d'] = date_to_iso(row['issue_d'])
writer.writerow(row)
except:
continue
#Validation function
def divisible_by_5(value):
try:
float_value = float(value)
if float_value % 5 == 0 and float_value != 0:
return float_value
else:
raise ValueError
except ValueError:
return None
At the moment, the writer is still writing rows that should be skipped. For example, if a number is not divisible by 5, instead of skipping that row, the writer is just writing ''.
So, how can I handle the exception (ValueError) raised in divisible_by_5 in my for loop so I don't write lines that raise an exception?
You can re-raise an exception caught in an exception handler and have another handler up the call stack handle it by using an empty raise statement inside the except block:
except ValueError:
raise # re raises the previous exception
This way, the outer handler in 'main' can catch it and continue.
Note: As is, your empty except: block in the for loop will catch everything. Specifying the exception expected (except ValueError in this case) is generally considered a good idea.
More simply, don't put the body of your validation function divisible_by_5 in a try statement. Python automatically searches for the nearest except block defined and uses it if the current exception matches the exceptions specified:
def raiser():
if False:
pass
else:
raise ValueError
try:
raiser()
except ValueError:
print "caught"
This will print caught.
From within an __exit__ block in a custom cursor class I want to catch an exception so I can in turn throw a more specific exception. What is the proper way to do this?
class Cursor:
def __enter__(self):
...
def __exit__(self, ex_type, ex_val, tb):
if ex_type == VagueThirdPartyError:
# get new more specific error based on error code in ex_val and
# return that one in its place.
return False # ?
else:
return False
Raising the specific exception within the __exit__ block seems like a hack, but maybe I'm over thinking it.
The proper procedure is to raise the new exception inside of the __exit__ handler.
You should not raise the exception that was passed in though; to allow for context manager chaining, in that case you should just return a falsey value from the handler. Raising your own exceptions is however perfectly fine.
Note that it is better to use the identity test is to verify the type of the passed-in exception:
def __exit__(self, ex_type, ex_val, tb):
if ex_type is VagueThirdPartyError:
if ex_val.args[0] == 'foobar':
raise SpecificException('Foobarred!')
# Not raising a new exception, but surpressing the current one:
if ex_val.args[0] == 'eggs-and-ham':
# ignore this exception
return True
if ex_val.args[0] == 'baz':
# re-raise this exception
return False
# No else required, the function exits and `None` is returned
You could also use issubclass(ex_type, VagueThirdPartyError) to allow for subclasses of the specific exception.