Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch exception output from Python subprocess.check_output()?

I'm trying to do a Bitcoin payment from within Python. In bash I would normally do this:

bitcoin sendtoaddress <bitcoin address> <amount> 

So for example:

bitcoin sendtoaddress 1HoCUcbK9RbVnuaGQwiyaJGGAG6xrTPC9y 1.4214 

If it is successful I get a transaction id as output, but if I try to transfer an amount larger than my bitcoin balance, I get the following output:

error: {"code":-4,"message":"Insufficient funds"} 

In my Python program I now try to do the payment as follows:

import subprocess  try:     output = subprocess.check_output(['bitcoin', 'sendtoaddress', address, str(amount)]) except:     print "Unexpected error:", sys.exc_info() 

If there's enough balance it works fine, but if there's not enough balance sys.exc_info() prints out this:

(<class 'subprocess.CalledProcessError'>, CalledProcessError(), <traceback object at 0x7f339599ac68>) 

It doesn't include the error which I get on the command line though. So my question is; how can I get the outputted error ({"code":-4,"message":"Insufficient funds"}) from within Python?

like image 741
kramer65 Avatar asked Jul 20 '14 11:07

kramer65


People also ask

What is the output of subprocess Check_output?

The subprocess. check_output() is used to get the output of the calling program in python. It has 5 arguments; args, stdin, stderr, shell, universal_newlines. The args argument holds the commands that are to be passed as a string.

How do I get output to run from subprocess?

To capture the output of the subprocess. run method, use an additional argument named “capture_output=True”. You can individually access stdout and stderr values by using “output. stdout” and “output.

How do you catch error in subprocess call?

Use Popen with the communicate() method when you need pipes. Show activity on this post. If you are fine with the program writing its output to stderr and you not directly interacting with it, the easiest way to do what you are asking is to use check_call instead of call .


1 Answers

According to the subprocess.check_output() docs, the exception raised on error has an output attribute that you can use to access the error details:

try:     subprocess.check_output(...) except subprocess.CalledProcessError as e:     print(e.output) 

You should then be able to analyse this string and parse the error details with the json module:

if e.output.startswith('error: {'):     error = json.loads(e.output[7:]) # Skip "error: "     print(error['code'])     print(error['message']) 
like image 168
Ferdinand Beyer Avatar answered Oct 26 '22 22:10

Ferdinand Beyer