This question already has answers here:
Exception handling when errors may occur in main program or in cleanup
(3 answers)
a cleaner way to approach try except in python
(6 answers)
Closed 9 months ago.
I am developing a python application. This is formed by the main.py script (~153 lines of code) full of functions that are written in other scripts.
There is some cleanup code at the end, but I would like to run this cleanup even if an error is raised. Searching about this, I have seen approaches like this
try:
# your program goes here
# you're calling your functions from here, etc
except SystemExit:
# do cleanup
raise
This means I have to introduce basically all scripts (from the first function to the end) between try and except. Is this the correct way to do this?
To run something regardless of error or not.
you can use the finally
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
Reading suggestions. So far the best approach I have found is this
try:
run_application()
# This is a function that takes all functions contain in main.py
except:
print('something went wrong')
finally:
do cleanup
# This is at the end of the main.py script
import sys
try:
print('my code')
# "type" of exception depends of Your script for example StandardError
except StandardError as err:
print('ERROR: {}'.format(err))
sys.exit(1)
#do cleanup
print('all OK')
print('cleanup code')
sys.exit(0)
Related
This question already has answers here:
What is the intended use of the optional "else" clause of the "try" statement in Python?
(22 answers)
Closed last year.
My question is where the difference between
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
and
try:
print("Hello")
print("Nothing went wrong")
except:
print("Something went wrong")
lies. The result seems identical to me. What are use cases to use the else statement?
Similarly, why would I ever use the finally statement?
try:
print(x) #Not defined before
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
and
try:
print(x) #Not defined before
except:
print("Something went wrong")
print("The 'try except' is finished")
again seems identical.
Edit:
I do know, what 'else' and 'finally' do. I just don't know when to use them as it seems you can reach an equivalent result without these statements.
The else block is only executes when no exception got raised. So
try:
f_noexception()
print("hello")
except Exception
pass
else:
print("Hello again")
Should give you two prints. Personallz, I think this is mildly useful and you actually don't see it being used very often.
However, finally is much more useful. The finally block gets always executed no matter if an exception was raised or not. So you can use that for doing some clean ups for example. Especially when you don't just catch an exception and handle it, but want it to get raised.
Answering to your 1st question:
Let's suppose there is an exception in your try block may be between these 2 lines
1.print("Hello")
2.print("Nothing went wrong")
In that case the second line will not be printed and the control will go to except block,so the output would not be the same.
The answers are same as there is no exception in your codes
So, when you have a code in which an exception might occur and you want something to get executed if that exception doesn't occur write it in else block.
Now answering to your 2nd question:
Finally is used when you want something to execute even if an exception occurs in try block.
Again your output are same because there is no exception in your try blocks.Try raising an exception and see the difference yourself.
finally keyword in Python
finally block is always executed after leaving the try statement. In case if some exception was not handled by except block, it is re-raised after execution of finally block.
finally block is used to deallocate the system resources.
One can use finally just after try without using except block, but no
exception is handled in that case.
finally block is executed regardless of exception is handled or not.
try:
print(x) #Not defined before
except:
print("Something went wrong")
finally:
#this block is always executed
# regardless of exception generation.
print('This is always executed')
Here, if your except block executes or not, finally block is always executed.
def directories():
print("Creating STRaitRazor directories...")
try:
os.chdir("C:\\")
os.mkdir("STRaitRazor")
os.chdir("STRaitRazor")
os.mkdir("Analysis")
os.chdir("Analysis")
os.mkdir("config")
os.mkdir("fastq")
os.chdir("..")
os.mkdir("bin")
os.chdir("bin")
print("STRaitRazor directories successfully created")
Sevenzip()
except:
print("Could not create directories. Do directories already exist?")
response = input("Y/N\n")
if response == "Y" or response == "y":
Sevenzip()
elif response == "N" or response == "n":
print("Unexpected exception occurred, aborting...")
time.sleep(5)
sys.exit(1)
def Sevenzip():
os.chdir("C:\\STRaitRazor\\bin")
try:
print("Downloading 7zip into C:\\STRaitRazor\\bin...")
url = "https://www.7-zip.org/a/7z1900.exe"
urllib.request.urlretrieve(url, "7zip.exe")
path = "C:/STRaitRazor/bin/"
subprocess.call("7zip.exe /S /D=%s"%path)
print("7zip downloaded")
gitdownload()
except:
print("Could not download 7-zip. Check your internet connection and admin permissions.")
response = input("Press ENTER to exit...")
sys.exit(1)
I'm having an issue with actually being able to exit my program after an exception. A sample of my code is above.
Basically what I'm doing is nesting functions inside other functions because this program needs to do several things in a specific order, so I'm starting at the top, checking to see if the function executed properly, and, if so, move onto to the next function.
My issue is with the exceptions. Everytime an exception is raised, the program doesn't exit when I tell it to. Instead, it raises the exception it should, then goes up a level and raises that exception and so on and so forth until it finally quits.
What exactly am I doing wrong?
Is it the way I've nested the functions?
Is there a way to force a program to quit no matter where the sys.exit(1) line is written?
sys.exit works by raising the SystemExit exception. Because you have a bare except instead of except SomeHypotheticalExceptionType, your exception handling is actually catching the SystemExit.
The minimal change to get the sys.exit to be respected would be except Exception:, but that isn't the best thing to do. It would be much better to only catch the exceptions that you expect to be raised and know how to handle. This is a generally accepted best-practice in python and it helps to avoid masking all sorts of nasty bugs that would otherwise go unnoticed (Imagine if you had misspelled the name of a variable -- surely you want the NameError to tell you that you did something wrong so you can fix it).
This question already has answers here:
How to continue with next line in a Python's try block?
(5 answers)
Closed 3 years ago.
sample:
with suppress(Exception)
os.remove('test1.log')
os.remove('test2.log')
try:
os.remove('test1.log')
os.remove('test2.log')
except:
pass
test2.log will not be deleted if test1.log isn't exist because FileNotFoundError. So how to process odd code after an exception happened, or how to prevent an exception been throw?
In a try-except if an exception is triggered, it will go the the except part than continue from there. So if you want to make sure both remove are attempted, do this:
try:
os.remove('test1.log')
except:
pass
try:
os.remove('test2.log')
except:
pass
Alternatively, you can try checking if the file exists, before deleting it:
if os.path.exists('test1.log'):
os.remove('test1.log')
if os.path.exists('test2.log'):
os.remove('test2.log')
As the duplicate explains, you can't just suppress the exceptions.
You probably want something like this:
files = ["test1.log", "test2.log"]
for file in files:
try:
os.remove(file)
except:
pass
tituszban already gave a valid solution.
You could also simply put your statements into a for-loop, which is shorter syntax since you don't have to repeat your try-catch blocks (especially useful when trying to delete more than 2 items).
lst = ["test1.log","test2.log"]
for element in lst:
try:
os.remove(element)
except:
pass
I am new to python I am learning exception handling now.
try:
print(1/0)
int(input("number"))
import bala
except ZeroDivisionError:
print("Divided by zero")
except KeyboardInterrupt:
print("dont press ctrl C!")
except ValueError:
print("Value should be number")
except ModuleNotFoundError:
print("Module not found")
The above code exits after first exception and the rest of the try statements are not executed. Should I use separate try-except block for each statement? Like this
try:
int(input("number"))
except ValueError:
print("Value should be number")
and
try:
import bala
except ModuleNotFoundError:
print("Module not found")
If an exception is raised that makes Python stop the execution immediately. You can prevent a complete program stop by using a try and except. However if an exception is raised in the try block, it will still stop execution right there and only continue if an appropriate except block catches the Exception (or if there is a finally block).
In short: If you want to continue with the next statements you need to use separate try and except blocks. But if you want to execute the next statements only if the previous statements didn't raise an Exception you shouldn't use separate try and except blocks.
Yes you need to have separate exception blocks because if it gets by the first block, it thinks thats all it needs to get by, so if you want to test every one, you should use separate ones
You have to use multiple try/except blocks.
Once an error is found, anything happening is stopped, and the exception is dealed with.
Think of it as a fire. When there is a fire you stop whatever and run out. For python it deals with the exception
I'm new to Python. I just want to know why the finally block is executing after calling sys.exit(0) in the except block?
Code:
import sys
def divide_by_zero():
try:
10/0
print "It will never print"
except Exception:
sys.exit(0)
print "Printing after exit"
finally:
print "Finally will always print"
divide_by_zero()
Btw., I was just trying to do the same thing as in Java, where the finally block is not executed when System.exit(0) is in the catch block.
All sys.exit() does is raise an exception of type SystemExit.
From the documentation:
Exit from Python. This is implemented by raising the SystemExit
exception, so cleanup actions specified by finally clauses of try
statements are honored, and it is possible to intercept the exit
attempt at an outer level.
If you run the following, you'll see for yourself:
import sys
try:
sys.exit(0)
except SystemExit as ex:
print 'caught SystemExit:', ex
As an alternative, os._exit(n) with the status code will stop the process bypassing much of the cleanup, including finally blocks etc.
You should use os._exit(0).
About your example:
A finally clause is always executed before leaving the try statement,
whether an exception has occurred or not.
This is from Error and Exceptions part of Python docs. So - your finally block will always be executed in example you show unless you will use os._exit(0). But you should use it wisely...