How do I return an exception? - python

I wrote a function that needs to do 3 checks and if one of the tests fails it should return an exception of type of LookupError, but it doesn't work.
(*verify_checksum is another function)
def check_datagram(datagram, src_comp, dst_app):
try:
src_comp==datagram[0:16]
except LookupError:
return "Mismatch in src_comp"
try:
dst_app==datagram[40:48]
except LookupError:
return "Mismatch in dst_app"
try:
verify_checksum(datagram)
except False:
return "Wrong checksum"
return True
For example:
Input:
check_datagram("1111000000001111000011111111000001010101101010101111111111111111000000001111111100000000","0000111100001111", "11110000")
Expected output:
"Mismatch in dst_app"

def check_datagram(datagram, src_comp, dst_app):
if src_comp != datagram[0:16]:
raise LookupError("Mismatch in src_comp")
if dst_app != datagram[40:48]:
raise LookupError("Mismatch in dst_app")
if not verify_checksum(datagram):
raise LookupError("Wrong checksum")
return True # redundant?

With construction from NPE's answer you should use try..except there where you'll use declared check_datagram() function.
#python3
try:
check_datagram(a,b,c)
except LookupError as e:
print(str(e))
That allow you to get message from raised error.

Related

How do i return error in exception in python?

I want to return the error in my code that I wrote in python. I can't do this. How can I do it?
def proc():
try:
a=2/0
except Exception as e:
print("Except")
raise f"{e}"
else:
return "Success"
result=proc()
print("result : ",result)
I tried using direct raise but it didn't work? How can I do?
If you just want to return the error message with the class name, you could probably do this:
def proc():
try:
a=2/0
except Exception as e:
print("Except")
return repr(e) # Repr is a great solution
else:
return "Success"
result=proc()
print("result : ",result)
Result:
Except
result : ZeroDivisionError(division by zero)

How to raise Exception with array?

I tried to throw an exception with array data:
raise Exception([ValidateError.YEAR, row])
When I tried to catch it I get this error:
'Exception' object is not subscriptable
Code is:
except Exception as e:
#invalid
print(e[0])
To access the Exception arguments you passed as a list, you should use .args.
So, I believe you were looking for the following:
except Exception as e:
#valid
print(e.args[0][0])
As a side note, you can pass multiple arguments without them being in a list:
raise Exception(ValidateError.YEAR, row)
And then you need one index less:
except Exception as e:
#also valid
print(e.args[0])
You can subclass Exception and implement the __getitem__ function like so:
class MyException(Exception):
def __init__(self, l):
self.l = l
def __getitem__(self, key):
return self.l[key]
try:
raise MyException([1, 2, 3])
except MyException as e:
print(e[0])
running it:
python3 main.py
1

Why a multiple inherited Exception does not catch the parent exception?

I'm assuming that following code suppose to print ("CustomExceptionALL"), but that never happens if we raise CustomException1, CustomException2 or CustomException3 while CustomExceptionALL works. Why except CustomExceptionALL doesn't catch CustomException3?
class CustomException1(Exception):
pass
class CustomException2(Exception):
pass
class CustomException3(Exception):
pass
class CustomExceptionALL(CustomException1, CustomException2, CustomException3):
pass
try:
raise CustomException3
except CustomExceptionALL as e:
print("CustomExceptionALL")
except Exception as e:
print(e)
The use case is more the other way round: you raise the derived exception and then catch it using the parent class. For example:
class Brexit(Exception):
pass
class Covid(Exception):
pass
class DoubleWhammy(Brexit, Covid):
pass
try:
raise DoubleWhammy
except Brexit as e:
print("Brexit")
except Exception as e:
print(e)
Because you can only catch subclasses of the specified exception. In your case, these two are false:
isinstance(CustomException3(), CustomExceptionALL) # False
issubclass(CustomException3, CustomExceptionALL) # False
(Because you are trying to catch a CustomExceptionALL, but a CustomException3 is not a CustomExceptionALL, but the other way around)
You can instead use a tuple of classes:
CustomExceptionALL = (CustomException1, CustomException2, CustomException3)
isinstance(CustomException3(), CustomExceptionALL) # True
issubclass(CustomException3, CustomExceptionALL) # True
try:
raise CustomException3
except CustomExceptionALL as e:
print("CustomExceptionALL") # This prints
except Exception as e:
print(e)

How to efficiently exit a python program if any exception is raised/caught

Say I have a block of exception statements:
try:
expression
except err1:
#process error
...
...
except err10:
#process error
and I want to call sys.exit(1) if ANY of the exceptions are raised. Do I have to call it manually in every single sub-block or is there a built in way to have a statement akin to:
...
except err10:
#process error
"if any of these exception were raised":
sys.exit(1)
One thing you could do is:
flag = False
try:
expression
flag = True
except err1:
#process error
...
...
except err10:
#process error
if not flag:
sys.exit(1) #exit program
If the flag is False, that means that you didn’t pass through the try loop, and so an error was raised.
In Python, there is an optional else block which is executed in case no exception is raised. You may use this to set a flag for you code and exit the code out of the try/except block as:
is_exception = True
try:
expression
except err1:
# ... something
except err10:
# ... something else
else:
# This will be executed if there is no exception
is_exception = False
if is_exception:
sys.exit(1)
raised = True
try:
expression
except err1:
# process error
raise
...
except err10:
# process error
raise
else:
# if no error was raised
raised = False
finally:
if raised:
raise SystemExit
Here's what I was talking about in my comment:
isok = False
try:
#try to do something
isok = True
except err1:
#do something besides raising an exception
except err5:
#do something besides raising an exception
if not isok:
raise SystemExit

Nested exceptions?

Will this work?
try:
try:
field.value = filter(field.value, fields=self.fields, form=self, field=field)
except TypeError:
field.value = filter(field.value)
except ValidationError, e:
field.errors += e.args
field.value = revert
valid = False
break
Namely, if that first line throws a ValidationError, will the second except catch it?
I would have written it un-nested, but the second filter statement can fail too! And I want to use the same ValidationError block to catch that as well.
I'd test it myself, but this code is so interwoven now it's difficult to trip it properly :)
As a side note, is it bad to rely on it catching the TypeError and passing in only one arg instead? i.e., deliberately omitting some arguments where they aren't needed?
If the filter statement in the inner try raises an exception, it will first get checked against the inner set of "except" statements and then if none of those catch it, it will be checked against the outer set of "except" statements.
You can convince yourself this is the case just by doing something simple like this (this will only print "Caught the value error"):
try:
try:
raise ValueError('1')
except TypeError:
print 'Caught the type error'
except ValueError:
print 'Caught the value error!'
As another example, this one should print "Caught the inner ValueError" only:
try:
try:
raise ValueError('1')
except TypeError:
pass
except ValueError:
print 'Caught the inner ValueError!'
except ValueError:
print 'Caught the outer value error!'
To compliment Brent's answer, and test the other case:
class ValidationError(Exception): pass
def f(a): raise ValidationError()
try:
try:
f()
except TypeError:
f(1)
except ValidationError:
print 'caught1'
try:
try:
f(1)
except TypeError:
print 'oops'
except ValidationError:
print 'caught2'
Which prints:
caught1
caught2

Categories