How to had try exception to log to logger using python - python

I have a Scenario where i want to check file exist at path or not
But if file not exist at path catch the error and log it to file using logging module and then script should break (exit). further code of lines should not be executed which is next function addtion_value if first function falls
Note : my script file contains lots of function one after the other in same file
Below is my code , i was able to code but with error
import path
import logging
logging.basicConfig(filename='log.txt',level=logging.INFO,format='%(asctime)',filemode='w')
def checkfileexist(Pth,Fle):
var=Path(Pth+'/'+Fle)
try :
if var.is_file():
logging.INFO('File found')
return (var)
exception Nofile as er:
logging.error('Not Found file')
else:
sys.exit()
def additionvalue(a,b):
return (a+b)
Is it possible to make use of import os module and create code ?

I have modified your script and it's working
import os
import logging
import sys
logging.basicConfig(filename='log.txt',level=logging.INFO,format='%(asctime)s- %(message)s',filemode='a')
def checkfileexist(Pth,Fle):
var=Pth+'/'+Fle
try :
if (var is None):
logging.error('Path is empty')
raise Exception("empty path")
if os.path.exists(var):
logging.error('File found')
return (var)
else:
raise Exception("File Not found")
except Exception as e:
logging.error('Not Found file')
sys.exit()
def additionvalue(a,b):
return (a+b)
you were not logging the message %(asctime)s- %(message)s as well as instead of 'w' you should use 'a' (append)

You can do it without raising any error:
def checkfileexist(Pth,Fle):
var = Path(Pth+'/'+Fle)
if var.is_file():
logging.info('File found')
return var
else:
logging.error('Not Found file')
But if you insist, you can do something like this:
def checkfileexist(Pth,Fle):
var = Path(Pth+'/'+Fle)
try:
if not var.is_file():
raise FileNotFoundError()
except FileNotFoundError as er:
logging.error('Not Found file')
else:
logging.info('File found')
return var
need to check both the parameter is passed to the function checkfilexist()
When you define a function with required parameters (as the function above), Python will already raise an error if you don't pass all its parameters:
checkfileexist()
# Raises TypeError: checkfileexist() missing 2 required positional arguments: 'Pth' and 'Fle'
checkfileexist('/c/d/',)
# Raises TypeError: checkfileexist() missing 1 required positional argument: 'Fle'
For the third case (raise an error if any argument is empty), you can do something like this:
def checkfileexist(Pth,Fle):
# Same as `if len(Pth) == 0:`
if not Pth:
raise TypeError("parameter Pth must not be empty")
# Same as `if len(Fle) == 0:`
if not Fle:
raise TypeError("parameter Fle must not be empty")
# ...

After all above answers and tried on my editor and prepared this below script
Correct me if any thing wrong in below code
Thanks for helping me with your approach: #lakshika-parihar #enzo & #Joaquim Procopio
But this worked for me
import os
import logging
import sys
logging.basicConfig(filename='C:\\Users\\admin\\Desktop\\JUL\\log.txt', level=logging.INFO,
format='%(asctime)s : %(message)s', filemode='w')
def checkfileexist(file_path, file_name):
try:
var_pth = str(file_path)
var_fle = str(file_name)
var_full = var_pth + var_fle
if var_pth is None or var_pth == '':
logging.error("Path parameter is empty")
raise TypeError('Path parameter is empty')
else:
pass
logging.info(f'Path : {var_pth}')
if var_fle is not None and var_fle != '':
pass
logging.info(f'Full : {var_fle}')
else:
logging.error("File parameter is empty")
raise TypeError('File parameter is empty')
if os.path.exists(var_full):
logging.error(f'File : {var_fle} is found at path : {var_pth} ')
logging.info(f'File : {var_full}')
return var_full
except:
logging.error(f"ERRO : {erron} ")
sys.exit()
try:
# Calling function
# checkfileexist('C:\\Users\\admin\\Desktop\\JUL\\', 'ABX')
# checkfileexist('', 'ABX') #Output : 2021-07-28 22:45:48,307 : Path parameter is empty
# checkfileexist('', '') #Output : 2021-07-28 22:46:53,758 : Path parameter is empty
checkfileexist() #2021-07-29 11:12:46,207 : ERROR : checkfileexist() missing 2 required positional arguments: 'file_path' and 'file_name'
except Exception as er:
logging.error(f"ERROR : {er} ")
sys.exit()

Related

Handling propagating errors

In my code I have a main function, which calls a function that reads some data from a file and returns this data, which is then used in diffrent ways. Obviously there is a risk that the user inputs a filename that is not to be found, resulting in an error. I want to catch this error and output a error message written by me without the traceback etc. I tried using a standard try-except statement, which works almost as intended, except now the data is not read so there are new errors as I try to calculate using empty variabels. Using sys.exit or raise SystemExit in the exception block results in errors beeig written in the console with tracebacks and the whole point of catching the first error feels redundant. I could wrap the whole program in a try-statement, but I have never seen that being done and it feels wrong. How can I either terminate the program in a clean way or hide all the subsequent errors?
def getData(fileName):
try:
file = open(fileName,"r")
data = file.readlines()
file.close()
x = []
y = []
for i in data:
noNewline = i.rstrip('\n')
x.append(float(noNewline.split("\t")[0]))
y.append(float(noNewline.split("\t")[1]))
return x,y
except FileNotFoundError:
print("Some error messages")
def main(fileName):
x,y = getData(fileName)
# diffrent calculations with x and y
Because main is a function, you could return on an error:
def main(filename):
try:
x, y = getData(filename)
except FileNotFoundError:
print("file not found")
return
# calculations here
Solution
sys.exit and SystemExit take optional arguments—0 is considered a successful termination.
Example
sys.exit(0)
raise SystemExit(0)
References
Python sys.exit: https://docs.python.org/3/library/sys.html#sys.exit
below
def getData(fileName):
file = open(fileName,"r")
data = file.readlines()
file.close()
x = []
y = []
for i in data:
noNewline = i.rstrip('\n')
x.append(float(noNewline.split("\t")[0]))
y.append(float(noNewline.split("\t")[1]))
return x,y
def main(fileName):
# if you only want to handle exception coming from 'getData'
try:
x,y = getData(fileName)
except Exception as e:
print(f'could not get data using file {filename}. Reason: {str(e)}')
return
# do something with x,y
if __name__ == "__main__":
main('get_the_file_name_from_somewhere.txt')

Python - try/except not working when variable assigned to sys.argv

I have this section in my code:
# I/O files
inp_arq = sys.argv[1]
out_arq = sys.argv[2]
pad_ref = "pad_ref03.fasta"
tes_mdl = "model_05_weights.best.hdf5"
and at the end:
try:
results_df.to_csv(out_arq,index = False)
print(f"File saved as: {out_arq}")
except IndexError:
print("No output file created")
If no file is passed in as out_arq (sys.argv[2]) it should run the script and print "No output file created" at the end. But I'm getting the "IndexError: list index out of range."
But if I comment out the "out_arq = sys.argv[2]" line and change the code to:
try:
results_df.to_csv(sys.argv[2],index = False)
print(f"File saved as: {sys.argv[2]}")
except IndexError:
print("No output file created")
It works and I got the message, but I'm not sure why. I'd like to have all my I/O file/vars at the begginig of the script, but with this one (out_arq) I can't.
How can I solve this? And why this happens?
If you look at the stack trace that is printed by the exception, you should see that the exception is raised on this line:
out_arq = sys.argv[2]
This is outside the try block, so the exception is not caught, and causes your program to terminate.
A solution is to check, before indexing the array, whether the element exists:
out_arq = sys.argv[2] if len(sys.argv) >= 3 else None
Then use if instead of try:
if out_arq:
results_df.to_csv(out_arq,index = False)
print(f"File saved as: {out_arq}")
else:
print("No output file created")

Error in try/except construction [duplicate]

This question already has an answer here:
Python try except else invalid syntax?
(1 answer)
Closed 6 years ago.
Im just sitting for 10 minutes staring at a simple piece of code, which I have copied from a guide and I can't understand why I am getting an error.
def transformation(x):
date_format = "%d/%m/%Y"
try:
a = dt.date(int(x[6:10]), int(x[3:5]), int(x[0:2]))
else:
a = dt.datetime.strptime(x, date_format)
finally:
return a
File "<ipython-input-91-f1f6fe70d542>", line 5
else:
^
SyntaxError: invalid syntax
Maybe this is just me... Whats wrong?
After adding except:
def transformation(x):
date_format = "%d/%m/%Y"
try:
a = dt.date(int(x[6:10]), int(x[3:5]), int(x[0:2]))
except pass
else:
a = dt.datetime.strptime(x, date_format)
finally:
return a
File "<ipython-input-93-c2285c857574>", line 5
except pass
^
SyntaxError: invalid syntax
You need an except clause to use else:
The try ... except statement has an optional else clause, which, when
present, must follow all except clauses
[Emphasis mine]
I just saw it from the python document page, so I'm just gonna quote what it says to you:
The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()

Checking if a registry key exists python

I am encountering a small hiccup in the installer I am creating in python. I have a function which returns the value of a key based on it's location.
def CheckRegistryKey(registryConnection, location, softwareName, keyName):
'''
Check the windows registry and return the key value based on location and keyname
'''
try:
if registryConnection == "machine":
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
elif registryConnection == "user":
aReg = ConnectRegistry(None,HKEY_CURRENT_USER)
aKey = OpenKey(aReg, location)
except Exception, ex:
print ex
return False
try:
aSubKey=OpenKey(aKey,softwareName)
val=QueryValueEx(aSubKey, keyName)
return val
except EnvironmentError:
pass
I get an error if the location does not exist. I want the function to return False so if the location does not exist so I can run the software installer, bit it always lands up in the exception
# check if the machine has .VC++ 2010 Redistributables and install it if needed
try:
hasRegistryKey = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))
if hasRegistryKey != False:
keyCheck = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))[0]
if keyCheck == 1:
print 'vc++ 2010 redist installed'
else:
print 'installing VC++ 2010 Redistributables'
os.system(productsExecutables + 'vcredist_x86.exe /q /norestart')
print 'VC++ 2010 Redistributables installed'
except Exception, ex:
print ex
The exception I get when I run the code is
'NoneType' object has no attribute '___getitem___'
and the error I get from the def CheckRegistryKey function is
[Error 2] The system cannot find the file specified
What I need to do is check if the registry key or location exists, if not direct it to an executable. Any help is appreciated.
Thank you
The reason for the error:
'NoneType' object has no attribute '___getitem___'
Is in the line:
keyCheck = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))[0]
The fragment edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed") is returning None.
This means you end up with:
keyCheck = (None)[0]
This is what is throwing your error. You are trying to get an item on a object that is None.
The reason that this you are getting None back from your CheckRegistryKey function is that if an error occurs you aren't returning anything. You need to return False when you catch a EnvironmentError:
try:
aSubKey=OpenKey(aKey,softwareName)
val=QueryValueEx(aSubKey, keyName)
return val
except EnvironmentError:
return False
I would also modify your code so that you are only calling CheckRegistryKey once:
registryKey = edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed")
if registryKey is not False:
keyCheck = registryKey[0]

Error when the Email formencode validator

I wanted to create an IDN-aware formencode validator to use in one of my projects. I used a portion of code from the Django project (http://code.djangoproject.com/svn/django/trunk/django/core/validators.py) to do that, but there must be a trivial error in my code I can't find :
class Email(formencode.validators.Email):
def _to_python(self, value, state):
try:
return super(Email, self)._to_python(value, state)
except formencode.Invalid as e:
# Trivial case failed. Try for possible IDN domain-part
print 'heywo !'
if value and u'#' in value:
parts = value.split(u'#')
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
try:
super(Email, self)._to_python(u'#'.join(parts), state)
except formencode.Invalid as ex:
raise ex
return value
else:
raise e
When I try to validate an email with an IDN domain (ex: test#wääl.de), the Invalid exception raised by the first call is thrown, and the portion of code after the first except is never executed ('heywo !' is never printed).
There is an example :
>>> from test.lib.validators import Email
>>> Email().to_python(u'test#zääz.de')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/FormEncode-1.2.3dev-py2.6.egg/formencode /api.py", line 416, in to_python
vp(value, state)
File "/usr/local/lib/python2.6/dist-packages/FormEncode-1.2.3dev-py2.6.egg/formencode /validators.py", line 1352, in validate_python
value, state)
Invalid: The domain portion of the email address is invalid (the portion after the #: z\xe4\xe4z.de)
What did I do wrong ?
Thanks.
Okay, found the answer. I was overloading _to_python instead of validate_python. The class now looks like :
class Email(formencode.validators.Email):
def validate_python(self, value, state):
try:
super(Email, self).validate_python(value, state)
except formencode.Invalid as e:
# Trivial case failed. Try for possible IDN domain-part
if value and u'#' in value:
parts = value.split(u'#')
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
try:
super(Email, self).validate_python(u'#'.join(parts), state)
except formencode.Invalid as ex:
raise ex
else:
raise e
It's working perfectly :)

Categories

Resources