How to get result from os.execvp() in python 2.7? - python

I am using os.execvp() function in python. I am not able to get result of this function.
try:
msi_install_cmd = ['msiexec.exe', '/quiet', '/i ', msi_path.encode('mbcs')]
os.execvp(msi_install_cmd[0], msi_install_cmd)
except Exception, error:
raise Exception("MSI installed failed")
Problem is not able to get return-code or exception from os.execvp().

os.exec*() and friends don't return by design. exec() replaces the current process with the one invoked. You could think of calling exec() as "stop doing my program here and continue with this program".
If you want the return code from a (child) process, the subprocess module is a better match:
try:
msi_install_cmd = ['msiexec.exe', '/quiet', '/i ', msi_path.encode('mbcs')]
subprocess.check_call(msi_install_cmd)
except Exception as error:
raise Exception("MSI installed failed: {}".format(error.message))

Related

How to catch PyGetWindowException when using pygetwindow in Python?

I have a script which uses pygetwindow module to do some operations on a specific window. While the script runs, I get the following exception:
File "C:\Program Files (x86)\Python38-32\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 237, in activate
_raiseWithLastError()
File "C:\Program Files (x86)\Python38-32\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 97, in _raiseWithLastError
raise PyGetWindowException('Error code from Windows: %s - %s' % (errorCode, _formatMessage(errorCode)))
pygetwindow.PyGetWindowException: Error code from Windows: 0 - The operation completed successfully.
I'm okay with the exception occurring but I want to catch this exception explicitly. I have done the following to try and catch this exception:
try:
#implementation
except pygetwindow.PyGetWindowException:
#handle exception
and
try:
#implementation
except PyGetWindowException:
#handle exception
Neither of the above catches the exception. If I use either of the above, I get another exception:
NameError: name 'PyGetWindowException' is not defined
or
NameError: name 'pygetwindow' is not defined
I don't want to catch the general Exception and then handle it since in case of other exceptions, I want to handle it differently. Is there something wrong in how I'm trying to catch this exception or is there a way to avoid this exception altogether?
EDIT: To be very clear, I have already imported pygetwindow.
You should have import pygetwindow at the begging of your script. It complains about not knowing what pygetwindow is.
Update
From the source file, it was clear that in order to use PyGetWindowException, you need to import the exception specifically (and not just import pygetwindow). Therefore, in order to catch the exception, one will have to do:
from pygetwindow import PyGetWindowException
After this import, you can use the exception in the normal way:
try:
#implementation
except PyGetWindowException:
#handle exception
Update 2
Another general way to do this would be to get the exception name from general exception and compare.
try:
try:
#implementation
except Exception as e:
if e.__class__.__name__ == 'PyGetWindowException':
#handle exception
else:
raise e
except Exception as e:
#handle other exceptions except pygetwindow exception
Original answer (not recommended)
Found a way to solve this question in this answer.
From the source of pygetwindow, it was clear that, whenever PyGetWindowException is raised, it is accompanied by the text:
"Error code from Windows:"
which indicates the error code given by Windows.
Based on this information, I did the following:
try:
try:
#Implementation
except Exception as e:
if "Error code from Windows" in str(e)
# Handle pygetwindow exception
else:
raise e
except Exception as e:
#handle other exceptions
This is another way (although the first one and second one are the correct and straightforward solutions) to solve the problem.

Is there a way to prevent the "bad connection" or "no network" error inside python?

I use urlopen command from urllib.request package and it works properly.
But because it is inside an infinite loop I want to consider the possible "No network" Conditions. I do not want my code to break down because of this error.
I tried the function below but it does not work:
def update():
try:
cmd = 'getUpdates'
resp = urlopen(URL + cmd)
line = aux_dec2utf8(resp)
upds = json.loads(line)
NoM = len(upds['result'])
except ValueError:
print('NO NETWORK')
return NoM, upds
Error Image
I think the issue here is the ValueError exception. You may want to set up an exception for urllib.HTTPError and/or urllib.URLError to catch the error you’re attempting to keep from breaking your script.
ValueError is used to catch an invalid argument and may not be what’s killing the flow.

How to print python exception thrown inside exec() function from outside

I am writing a little software for executing python codes and I want to print exceptions. The following function gets executed:
def run(self, mode='activate'):
try:
exec(self.mycode)
except Exception:
print(traceback.format_exc())
There is no information about what exactly will be executed in the exec() function, it can literally be any python code. I want to print an exception thrown (mostly automatically by python due to code errors) somehow like shown, while executing via exec() including the line of code passed into the exec() function where the exception has been thrown.
I so far only managed to get the 'exec(mycode)' as exception code output, but I want the actual line of code that crashed in mycode.
try this :
def run(self, mode='activate'):
try:
exec(your_code)
except Exception as e:
print(e)
This would work!
add this line traceback.print_exc()
def run(self, mode='activate'):
try:
exec(your_code)
except Exception as e:
print(e)
traceback.print_exc()
This would give you the exception information and also will give you line number where the exception/error occurred!

suggestions for to improve my python function to parse Wordpress/config.php

I am writing a python script function to backup Wordpress. As part of the script i wrote a function to fetch database details from the config.php file.
Working of my function
function takes Wordpress installation location as an argument and using regex to match db_user,db_host,db_user,db_password from that file, the function will exist if can not find "config.php". I am using sys.exit(1) to exit from the function is that the proper way to exit from a function? I am pasting my function code snippet.
def parsing_db_info(location):
config_path = os.path.normpath(location+'/config.php')
if os.path.exists(config_path):
try:
regex_db = r'define\(\s*?\'DB_NAME\'\s*?,\s*?\'(.*?)\'\s*?'.group(1)
regex_user = r'define\(\s*?\'DB_USER\'\s*?,\s*?\'(.*?)\'\s*?'.group(1)
regex_pass = r'define\(\s*?\'DB_PASSWORD\'\s*?,\s*?\'(.*?)\'\s*?'.group(1)
regex_host = r'define\(\s*?\'DB_HOST\'\s*?,\s*?\'(.*?)\'\s*?'.group(1)
db_name = re.match(regex_db,config_path).group(1)
db_user = re.match(regex_user,config_path).group(1)
db_pass = re.match(regex_pass,config_path).group(1)
db_host = re.match(regex_host,config_path).group(1)
return {'dbname':db_name , 'dbuser':db_user , 'dbpass':db_pass , 'dbhost':db_host}
except exception as ERROR:
print(ERROR)
sys.exit(1)
else:
print('Not Found:',config_path)
sys.exit(1)
AFTER EDITING
def parsing_db_info(location):
config_path = os.path.normpath(location+'/wp-config.php')
try:
with open(config_path) as fh:
content = fh.read()
regex_db = r'define\(\s*?\'DB_NAME\'\s*?,\s*?\'(.*?)\'\s*?'
regex_user = r'define\(\s*?\'DB_USER\'\s*?,\s*?\'(.*?)\'\s*?'
regex_pass = r'define\(\s*?\'DB_PASSWORD\'\s*?,\s*?\'(.*?)\'\s*?'
regex_host = r'define\(\s*?\'DB_HOST\'\s*?,\s*?\'(.*?)\'\s*?'
db_name = re.search(regex_db,content).group(1)
db_user = re.search(regex_user,content).group(1)
db_pass = re.search(regex_pass,content).group(1)
db_host = re.search(regex_host,content).group(1)
return {'dbname':db_name , 'dbuser':db_user , 'dbpass':db_pass , 'dbhost':db_host}
except FileNotFoundError:
print('File Not Found,',config_path)
sys.exit(1)
except PermissionError:
print('Unable To read Permission Denied,',config_path)
sys.exit(1)
except AttributeError:
print('Parsing Error wp-config seems to be corrupt,')
sys.exit(1)
To answer your question, you shouldn't normally use sys.exit inside a function like that. Rather, get it to raise an exception in the case where it fails. Preferably, it should be an exception detailing what went wrong, or you could just let the existing exceptions propagate.
The normal rule in Python is this: deal with exceptions at the place you know how to deal with them.
In your code, you catch an exception, and then don't know what to do, so call sys.exit. Instead of this, you should:
let an exception propagate up to a top-level function which can catch it, and then call sys.exit if appropriate
wrap the exception in something more specific, and re-raise, so that a higher level function will have a specific exception to catch. For example, your function might raise a custom ConfigFileNotFound exception or ConfigFileUnparseable exception.
Also, you have put except exception, you probably mean except Exception. However, this is extremely broad, and will mask other programming errors. Instead, catch the specific exception class you expect.

Print Python Exception Type (Raised in Fabric)

I'm using Fabric to automate, including the task of creating a directory. Here is my fabfile.py:
#!/usr/bin/env python
from fabric.api import *
def init():
try:
local('mkdir ./www')
except ##what exception?##:
#print exception name to put in above
Run fab fabfile.py and f I already have ./www created an error is raised, but I don't know what kind, so I don't know how to handle the error yet. Fabric only prints out the following:
mkdir: cannot create directory ‘./www’: File exists
Fatal error: local() encountered an error (return code 1) while executing 'mkdir ./www'
Aborting.
What I want to do is be able to find out the error type so that I can except my errors properly without blanket statements. It would be really helpful if an answer does not just tell me how to handle a mkdir exception, but print (or otherwise find the name to) any exception I may run into down the line (mkdir is just an example).
Thank you!
The issue is that fabric uses subprocess for doing these sorts of things. If you look at the source code for local you can see it doesn't actually raise an exception. It calls suprocess.Popen and uses communicate() to read stdout and stderr. If there is a non-zero return code then it returns a call to either warn or abort. The default is abort. So, to do what you want, try this:
def init():
with settings(warn_only=True):
local('mkdir ./www')
If you look at the source for abort, it looks like this:
10 def abort(msg):
21 from fabric.state import output
22 if output.aborts:
23 sys.stderr.write("\nFatal error: %s\n" % str(msg))
24 sys.stderr.write("\nAborting.\n")
25 sys.exit(1)
So, the exception would be a SystemExit exception. While you could catch this, the proper way to do it is outlined above using settings.
It is nothing to handle with exception, it is from the fabric api
try to set the entire script's warn_only setting to be true with
env.warn_only = True
Normally, when you get an uncaught exception, Python will print the exception type along with the error message:
>>> raise IOError("Error message.")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: Error message.
If that's not happening, you're probably not getting an exception at all.
If you really want to catch an arbitrary exception and print it, you want to catch Exception or BaseException. BaseException will include even things like KeyboardInterrupt, though, so be careful with that.
def init():
try:
local('mkdir ./www')
except BaseException as e:
print "local() threw a", type(e).__name__
raise # Reraise the exception
In general:
try:
some_code()
except Exception, e:
print 'Hit An Exception', e
raise
Will tell you what the exception was but if you are not planning on actually handling some of the exceptions then simply getting rid of the try: except: lines will have exactly the same effect.
Also if you run your code under a debugger then you can look at the exception(s) that you hit in more detail.
def init():
try:
local('mkdir ./www')
except Exception as e:
print e.__class__.__name__
That's all there is to it!
edit: Just re-read your question and realized that my code would only print "Fatal" in your case. It looks like fabric is throwing an error and returning their own error code so you would have to look at the documentation. I don't have any experience with fabric so I'd suggest to look here if you haven't already. Sorry if this isn't helpful!

Categories

Resources