# How can I catch reports from Operators in Python script?

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?

• 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 – TLousky Jan 14 '16 at 23:51
• @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. – xuv Jan 15 '16 at 0:31
• 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. – TLousky Jan 15 '16 at 0:33
• @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. – xuv Jan 15 '16 at 0:56
• – p2or Jan 15 '16 at 10:58

## For Operator Error Reports

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

import bpy
try:
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)
print("Report was %r" % output)


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
logfile.seek(0)

• Better to use contextlib, otherwise a problem with the script can leave stdout set. – ideasman42 Jan 21 '16 at 2:46