How can I turn VTK pipeline errors into python exceptions?

I am using VTK to write files in a highly parallelized python application across multiple nodes. Because of the libraries I use (parsl), the stdout and stderr messages are all “swallowed”, giving me no access to VTK errors. When something goes wrong inside the pipeline, the VTK code sliently fails.

A solution would be to convert all VTK errors to python exceptions.

I can raise errors by using VTK’s AddObserver functions. However, this does not catch Pipeline errors (such as vtkCompositeDataPipeline errors). The following example fails (unstructured grid cannot be put into a STL Writer), but does not raise a python Exception:

import vtk

ug = vtk.vtkUnstructuredGrid()
pts = vtk.vtkPoints()
pts.InsertNextPoint( 0,1,2 )
ug.SetPoints( pts )

#pd = vtk.vtkPolyData()
#pts = vtk.vtkPoints()
#pd.SetPoints( pts )

def observer( a, b ):
    raise Exception( a, b )

w = vtk.vtkSTLWriter()
w.AddObserver( "ErrorEvent", observer )
w.SetFileName( "123.stl" )
w.SetInputData( ug )
w.Update()

How do I turn all VTK errors into python exceptions? I read something about vtkOutputWindow usage, but haven’t found examples of how to use this to raise exceptions…?

Ideally, I’d like to enable this globally, because there are so many different places where I use VTK… and adding these observers everywhere can get very tedious.

Anyone know how I can achieve this?

Briefly, you can’t. When a VTK object calls a Python observer, VTK catches the exceptions, prints them, and then continues running. The VTK object doesn’t re-throw the Python exceptions after catching them.

There is a reason why VTK does this. Let’s say you call a VTK function like Update(). That Update function might invoke several events. Let’s say that one of those events goes to your observer and raises a Python exception. Ideally, you would want the exception to go straight back to the Update() where you can catch it, but VTK doesn’t use exception-based error handling. After the error, VTK will continue processing whatever it is able to, and it might invoke additional events. This could lead to instability if the original Python exception was left un-handled and another Python exception occurred before VTK finished the Update().

Hey, thanks!

I think I figured out a solution that works in my case!

I understand that the whole process is complicated, but for my purposes, all I needed to do was get notified when there is a wrong data type sent to the algorithm (which seemed to manifest itself as an error in the pipeline, rather than the algorithm) so that I can then abort directly and raise a python Exception (in order to avoid those downstream errors you mention, which would be very difficult for the users to deal with, especially because stdout/stderr is not passed on by the application).

The solution I found was that I can get the vtkExecutive from the algorithm and add an observer to that as well:

    writer = vtk.vtkSTLWriter()
    writer.AddObserver( "ErrorEvent", observer )
    writer.GetExecutive().AddObserver( "ErrorEvent", observer )
    writer.SetFileName( filename )
    writer.SetInputData( mesh )
    writer.Update()