I am using the following in a script:
try:
subprocess.check_output(file_path,shell=True)
except:
print("Error: Unable to open file.")
This code works mostly as intended with the only problem being that it still throws an exception on successful operations.
I will be using this with Tkinter to display message boxes and don't want my users to receive an error every time they close their successfully opened file. I am a bit of a novice and don't understand the subprocesses as well as I'd like to. I was originally using .Popen but from what I read, check_output is the best way to catch the exception.
Is there something I am missing or an easy way to fix this?
Edit: I checked the error via this method:
try:
subprocess.check_output(file_path, shell=True)
except subprocess.CalledProcessError as e:
print(e.output)
it just returns
b''
When I add print(e), I get this:
Command '<file_path>' returned non-zero exit status 1.
where the <file_path> is the actual path to the file.
I've also tried using .Popen and then .communicate() to view the output and error, but both return none whether-or-not .Popen has a target. If there is no target, I also see this in cmd:
<file_path> is not recognized as an internal or external command,
operable program or batch file.
Basically, I just want to throw an error if the target file path is not valid. If it is valid, I want it to open the file. I don't need to know the error, just that the file doesn't exist.
Related
try:
some code here
except Exception as e:
print("error: ",e)
here if this python exe code produces an exception it immediately closes the exe terminal
how do I stop it from exiting the exe terminal so that I can understand what exception exactly occurred
also I cant run it in CMD I have to run the exe file only
also I cant use the press any key method
The terminal closes when the program terminates. When you catch the exception, you print your error message, and then the program terminate, so you don't really gain much from catching the exception; in fact, you even get less (you don't print the stack trace).
To get the stacktrace, look into traceback:
try:
foo = 123 / 0
except Exception as e:
traceback.print_exception(e)
Then you need to have the program wait a bit that you can actually see the stack trace and error you print. A simple way is to just wait for input:
try:
foo = 123 / 0
except Exception as e:
traceback.print_exception(e)
wait_for_it = input('Press enter to close the terminal window')
Or you could add a break point to have the Python debugger pdb come up. (It does at least on Mac OS when I run this code in a terminal, no idea about Windows.) See the above link for help on it, or type help at its prompt.
try:
foo = 123 / 0
except Exception as e:
breakpoint()
Speaking of terminal: if you just open a command prompt or bash terminal, you can just run your code with python3 myprog.py and that terminal does not automatically close, so that you can see the output without modifying the program. Depending on how you run your code and what module dependencies you have, this may need a bit more setup (like a virtual environment) but is probably worth it in the long run.
Is there a doc somewhere which indicates what the different return codes of python's subprocess check_output() command means? I'm seeing the returncode equal 3, and I have no idea what is setting that value and/or what it means.
Example code:
try:
output = subprocess.check_output(cmd,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
print e.returncode
This code is printing 3.
The Python subprocess.check_output() doesn't itself return a code, it returns the output of the command being run. The doco can be found here.
If you're seeing an error code in that string, it's almost certainly specific to whatever you're trying to run, not a result of subprocess itself.
If, however, you're capturing the CalledProcessError exception caused by a non-zero return code (which can be extracted from the returncode attribute), that's still specific to whatever you're running.
In both cases, the documentation you need to check is that of whatever tool subprocess is running.
I have a test that is calling a script using subprocess.check_call. I have assertions inside the script checking the validity of the arguments and I want to check the error cases. So I've done this:
try:
self.assertRaises(subprocess.CalledProcessError, subprocess.check_call, ['myscript.py', 'myBadArgument'])
except AssertionError:
pass
The test actually passes since the correct assertion gets raised, but I want to keep the assertion messages and associated stack dump from getting printed to the screen.
How do I do this?
Thanks!
To suppress the subprocess's error messages, redirect its stderr:
from subprocess import DEVNULL
with self.assertRaises(subprocess.CalledProcessError):
subprocess.run(['myscript.py', 'myBadArgument'], stdout=DEVNULL, stderr=DEVNULL)
Also, don't catch AssertionError. That doesn't do anything to suppress the subprocess's error messages; it only causes your test to incorrectly pass even if the subprocess doesn't raise an error.
The problem here was that I was overusing the assert() statement. I was using assert to check for things such as whether the user gave me files that existed, or values that made sense in the script.
This was a misunderstanding on my part. I now see that the correct approach is to check the data and raise the appropriate exceptions in my library elements, then catch those exceptions in my user-facing scripts and provide a call-stack free message.
Once I cleaned this up my test passed with the correct exceptions and with no unneeded messages.
I wonder if there is a way to capture any (and all) type of error that crashes the script, but potentially without using try to catch a specific exception.
I have a webdriver script that does a lot of stuff, like clicks on links, sends keys and so on, but I cannot predict where it will crash. I want to run a series of tests in sequence and print results into a file - including any errors/crashes:
Eg.
Test01 - Success!
Test02 - NameError: name 'driver' is not defined !ERROR!
Test03 - Success!
and so on.
So that at the end I can just open the text file and check which tests need to be fixed and re-run.
Now I've been using try/exception with smaller blocks of code, but it seems to me that I would have to somehow include the whole script within try/catch/exception to get what I want.
Is there a better way to catch any type of error that is displayed after a script crashes, like on the image below:
You can use a plain except to catch any and all exceptions, like so:
try:
some code here
except:
print 'whoops, something went wrong'
However this doesn't give you any information about the exception, so you probably don't want to do that.
You can also catch the very broad Exception, like so:
try:
some code here
except Exception as ex:
print 'oops, caught this error: %s' % ex
This is a better method as it tells you what exactly went wrong.
It seems the trick you are looking for is redirecting the stderr to a file or stdout.
Python when having the exception will write the exception to stderr .
simply you need to redirect stderr to the same output file you have when running the python program
like this
python file.py &> outputfile
I am trying to run unoconv to convert a set of documents in a folder like so:
import subprocess
try:
subprocess.check_call(['unoconv', "/home/foo/ve/pdf/pdf/pdf_media/" + <filename parameter>)
except subprocess.CalledProcessError as e:
print "conversion error: ", e
Now, I run the above code within a django view - and it runs as expects all the time i.e converts the document to PDF, but, sometimes, the above code throws me the following exception:
Command '['unoconv', u'/home/foo/ve/pdf/pdf/pdf_media/WgYozM7.doc']' returned non-zero exit status -8
However, when I go to the folder, I see that the conversion has happened and the PDF generated as expected.
I fail to understand what this exit code means (I searched the docs of unoconv but couldnt find any exit code 8).
It looks to me that your subprocess has a negative exit-code. This is not an application code, but caused by the OS terminating your program. The negative number is the signal-number the process received. On my mac, -8 stands for SIGFPE.