6
$\begingroup$

Is it possible to catch reports from Operators in a Python script?

For example, the Operator bpy.ops.object.modifier_apply() shows errors in the console when something goes wrong. I'd be happy to have a try... catch... method to handle those.

Same with some addons like 3D Print Toolbox who send back useful info in the console and UI, but I can't seem to find a way to catch those. Is this possible?

Update:
To give a concrete example, this file uses a boolean modifier on two objects and when applied, the Operator returns a lot of WARNING or errors in the console. How could I catch those?

$\endgroup$
9
  • $\begingroup$ This isn't really a blender question so much as a python question. What you're looking for is error handling in python, and here's the docs about that: docs.python.org/3/tutorial/errors.html $\endgroup$
    – TLousky
    Jan 14, 2016 at 23:51
  • $\begingroup$ @TLousky Sorry if my question is badly formulated. But Operators can report data or info or messages when they fail, operate or succeed. So I'm not maybe going to use try... catch, but if I could somehow access those reports, that would be useful. $\endgroup$
    – xuv
    Jan 15, 2016 at 0:31
  • $\begingroup$ OK, if the operator failed but did not trigger an exception that stops the script, you will be able to see the result in the operator's return value: res = bpy.ops.some_operator(). Common values are {'FINISHED'}, {'CANCELED'} and {'RUNNING_MODAL'}, among others. $\endgroup$
    – TLousky
    Jan 15, 2016 at 0:33
  • $\begingroup$ @TLousky: Ok. Thx. Yes, that works. But I'm not interested in what an operator returns, but at the calls to the report() function from those Operators. For a particular and specific example, in the 3D Print Toolbox addon, at line 477, the Operator.report() function is called. That's what I'm trying to catch. $\endgroup$
    – xuv
    Jan 15, 2016 at 0:56
  • $\begingroup$ related: blender.stackexchange.com/questions/18874/… $\endgroup$
    – p2or
    Jan 15, 2016 at 10:58

2 Answers 2

10
$\begingroup$

For Operator Error Reports

Catching Errors is handled separately, this example catches the error report and prints it as a string.

import bpy
try:
    bpy.ops.object.vertex_group_add()
except RuntimeError as ex:
    error_report = "\n".join(ex.args)
    print("Caught error:", error_report)

For Operator Info Reports

Python can temporarily redirect the stdout using contextlib, this is ideal since you may not want to suppress output for _all_ scripts, just selectively redirect some output.

eg:

import bpy

import io
from contextlib import redirect_stdout

stdout = io.StringIO()
with redirect_stdout(stdout):
    bpy.ops.mesh.remove_doubles()

If you want you can read the output back out or use it however you like.

stdout.seek(0)
output = stdout.read()
print("Report was %r" % output)
$\endgroup$
0
$\begingroup$

This is a hack I found to solve parts of this problem. It will work with Operators using the report() function to display data back to the user but don't provide a way to catch that data in other ways.

Those reports are both displayed in the Information window and in the console. So the trick I found is to do temporarily reroute the stdout from Python to a text file and re-read the text file afterwards.

# Opens a text file to write the reports
def openLogs():
    logfile = open( bpy.path.abspath('//') + "log.txt", "r+")
    # reroute stdout to the logfile
    sys.stdout = logfile
    return logfile

# Reads the file content and closes it
def readAndCloseLogs( logfile ):
    logfile.seek(0)
    logs = logfile.readlines()
    logfile.close()
    # Return stdout to its normal state
    sys.stdout = sys.__stdout__
    return logs

# Then wrap your operator between these two functions
logfile = openLogs()
# bpy.ops... # Put your operator here 
logs = readAndCloseLogs( logfile )

# The logs contains what the Operator has reported
$\endgroup$
1
  • $\begingroup$ Better to use contextlib, otherwise a problem with the script can leave stdout set. $\endgroup$
    – ideasman42
    Jan 21, 2016 at 2:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .