Catching exception, raising custom exception that ends with sys.exit - python

I want to catch an exception, raise a custom exception, and then sys.exit(0) to exit the program gracefully.
I have tried the following:
In my main execution code, I have this:
try:
(some code)
except Exception as ex:
raise CustomException
and in CustomException class:
class CustomException(Exception):
def __init__(self):
sys.exit(0)
Unfortunately my custom exception is not getting raised this way and the main Exception is not getting caught.
I understand I could raise SystemExit but I need to generate a custom exception for me to catch in another code block down the road.

Related

How to catch an error thrown inside an imported module

I have a custom module with a function, and I am importing it to my main file. When there is an exception raised in the module, I want to catch it in the main file.
Is this possible? I'm having a hard time finding any examples of this online or in the exception documentation.
Example:
exceptionStuff.py
class My_Error(Exception):
pass
def Fail_Func():
raise Exception
main.py
from myModules.exceptionStuff import My_Error
try:
My_Error()
except:
print('caught')
The exception doesn't get caught here.
If you reorganize exceptionStuff.py like this
class My_Error(Exception):
pass
def Fail_Func():
raise My_Error
And your main file like this
from exceptionStuff import My_Error, Fail_Func
try:
Fail_Func()
except My_Error as e:
print(e.__class__.__name__)
print('caught')
You will successfully catch an exception of type My_Error.
Output:
My_Error
caught

How to handle multiple exceptions

If I have a code that raises more exceptions simultaniously like this
class A(Exception): pass
class B(Exception): pass
try:
try:
raise A('first')
finally:
raise B('second')
except X as c:
print(c)
Is there a way for handle all the exceptions toghether?
You can handle them all in this way:
except (A, B) as c:
Also you can define your own base class for your exceptions:
class BaseCustomException(Exception): pass
class A(BaseCustomException): pass
class B(BaseCustomException): pass
After it you can catch base exception, it will cover all derived exceptions:
except BaseCustomException as c:
When an new exception is thrown in a catch block or finally block that will propagate out of that block, then the current exception will be aborted (and forgotten) as the new exception is propagated outward. The new exception starts unwinding up the stack just like any other exception, aborting out of the current block (the catch or finally block) and subject to any applicable catch or finally blocks along the way.
check:Exception thrown in catch and finally clause

Logging custom exceptions Python

I have a simple try and except statement. However I want to use logger exception to log the exception. What is the best way of only have 1 line of code for the logger.exception. In the exception base class ?
try:
do_something()
except CustomBaseExecption, exc:
logger.exception("Exception Raised:")
raise GeneralError(exc)
except Exception as exc:
logger.exception("Exception Raised:")
raise GeneralError("Unknown Error")
Only thing that's changed between two code blocks is GeneralError argument. Let's put a conditional there.
try:
do_something()
except Exception as exc:
logger.exception("Exception Raised:")
raise GeneralError(exc if isinstance(exc, CustomBaseExecption) else "Unknown Error")

python: raise("customException") - why no stack trace?

Using custom exceptions in python (v2.7.3): don't get a stack trace when call getSub() whereas getSub(True) invokes one, the difference being that it is caused via an additional try...except which I want to avoid (+feels unnecessary) so why/how can it be avoided?
import sys, traceback
class customException(Exception):
def __init__(self, *args):
super(customException,self).__init__(*args)
print "Stack trace within exception", traceback.extract_tb(sys.exc_info()[2])
errTxt = [a for a in args]
print "error text", errTxt
def getFn():
try:
getSub()
except customException as e:
print "customException was raised"
try:
getSub(True)
except customException as e:
print "customException2 was raised"
def getSub(flag=False):
if flag:
try:
1/0
except:
raise customException('test')
else:
raise customException('test')
getFn()
output:
Stack trace within exception []
error text ['test']
customException was raised
Stack trace within exception [('./test3.py', 25, 'getSub', '1/0')]
error text ['test']
customException2 was raised
To put the above in context I have code (pseudo) along the below lines and it wasn’t until I boiled down the code to the above example that I realised why the traceback access was not always working. The purpose of the custom exception class is to collect an aggregate count of exceptions in order to classify downstream the result of each do_something, e.g. fatal, warning etc. The use of the traceback was to record from WHERE the exception was ‘raised’ and therefore the creation of an exception (1/0 = albeit seems out of place) enables that to work. Wondering about using the inspect module rather than thinking about this within the traceback stack?
__main__
With each item in set:
Try:
do_something(item)
except customException()
clean up = log info etc.
end With
end.__main__
do_something(item)
try:
check_something()
except customException
if exception=typeA.1 raise customException(Type1)
if exception=typeB.2 and item = ‘x’
raise customException(Type2)
check_something()
a = getInfo()
unless getInfo()
raise customException(typeA.1)
try:
b = getOtherInfo()
except customException
raise customException(typeB.2)
…
If I understand you right, you're wondering why your print "Stack trace within exception" line prints an empty list for getSub(), but prints some traceback info for getSub(True).
You have code in your exception class's __init__ to look at the most recent exception via sys.exc_info. When you do raise customException('test'), customException('test') is evaluated first on its own, before it "knows" that it is going to be raised as an exception. So when you do that raise in getSub(), there is no most recent exception.
With getSub(True), there is a most recent exception, because the 1/0 raises an exception before you create your customException. Note that when you do 1/0, the most recent exception is the one from that 1/0; you can see that there's nothing about your customException in that traceback.
An exception object has to be created before the exception is raised. So you can't look at "the current exception" in your exception class's __init__ to get info about the stack trace that will be created when it is raised, because it hasn't been raised yet at that time.
If you want, you could use traceback.extract_stack to get the call stack at the time the exception object is created, but there's no guarantee that that has anything to do with when it will be raised. Just because an instance of your exception class is created doesn't even mean it will ever be raised at all. It's perfectly legal (although generally pointless) for someone to just create an exception object with stuff = customException('blah') but never actually raise the exception.
In any case, it's not clear from your question what you're trying to achieve here. It would help if you explained that.
Because you're catching the exception, there will be no traceback unless you either explicitly re-raise
try:
getSub(True)
except customException as e:
print "customException2 was raised"
raise # add this to re-raise, with original traceback
or print it yourself:
try:
getSub(True)
except customException as e:
print "customException2 was raised"
print traceback.format_exc()

except block does not catch the exception in python

my code is like below
class Something(models.Model)
def exception(self)
try:
Something.objects.all()
except Exception():
raise Exception()
called this method from testcases ,its working but i need to raise exception ,it does not catch the exception
and here is my test case
def test_exception(self):
instance = Something()
instance.exception()
its working fine but i need to raise exception from except block
This line:
except Exception():
should be:
except Exception:
def exception(self)
try:
Something.objects.all()
except Exception, err:
#print err.message (if you want)
raise err
This will catch the error and print the exact msg if required.
Why catch the Exception just to re-raise it?
If you are not doing anything in the except suite except re-raising the exception, then simply do not catch the exception in the first place:
#staticmethod
def exception():
Something.objects.all()
If you are doing something nontrivial inside the except suite, then:
def exception(self):
try:
Something.objects.all()
except Exception:
# do something (with self?)
raise
Then, to test that the exception method raises an Exception:
def test_exception(self):
instance = Something()
self.assertRaises(Exception, instance.exception)
This depends on Something.objects.all() raising Exception.
PS. If exception does not depend on self, then it is best to remove it from the argument list and make exception a staticmethod.
PPS. Exception is a very broad base exception class. A more specific exception would be more helpful for debugging, and allow other code to catch this specific exception instead of forcing it to handle any possible Exception.

Categories