@@ -23,9 +23,26 @@ class UVisualizer(ctypes.Structure):
2323 # Visualizer creation and destruction
2424 helios_lib .createVisualizer .argtypes = [ctypes .c_uint32 , ctypes .c_uint32 , ctypes .c_bool ]
2525 helios_lib .createVisualizer .restype = ctypes .POINTER (UVisualizer )
26+
27+ # Add errcheck to automatically handle errors and nulls
28+ def _check_visualizer_creation (result , func , args ):
29+ if _ERROR_MANAGEMENT_AVAILABLE :
30+ check_helios_error (helios_lib .getLastError , helios_lib .getLastErrorMessage )
31+ if not result :
32+ raise RuntimeError (
33+ "Failed to create Visualizer. This may indicate:\n "
34+ "1. OpenGL/graphics initialization problems in headless environments\n "
35+ "2. Missing graphics drivers or display support\n "
36+ "3. Insufficient system resources for graphics context creation\n "
37+ "4. XQuartz or display server configuration issues on macOS/Linux"
38+ )
39+ return result
40+
41+ helios_lib .createVisualizer .errcheck = _check_visualizer_creation
2642
2743 helios_lib .createVisualizerWithAntialiasing .argtypes = [ctypes .c_uint32 , ctypes .c_uint32 , ctypes .c_uint32 , ctypes .c_bool ]
2844 helios_lib .createVisualizerWithAntialiasing .restype = ctypes .POINTER (UVisualizer )
45+ helios_lib .createVisualizerWithAntialiasing .errcheck = _check_visualizer_creation
2946
3047 helios_lib .destroyVisualizer .argtypes = [ctypes .POINTER (UVisualizer )]
3148 helios_lib .destroyVisualizer .restype = None
@@ -118,25 +135,21 @@ def create_visualizer(width: int, height: int, headless: bool = False) -> Option
118135 )
119136
120137 try :
138+ # The errcheck callback will handle error checking and null pointer validation
121139 visualizer = helios_lib .createVisualizer (
122140 ctypes .c_uint32 (width ),
123141 ctypes .c_uint32 (height ),
124142 ctypes .c_bool (headless )
125143 )
126- _check_for_helios_error ()
127-
128- if not visualizer :
129- raise RuntimeError ("Failed to create Visualizer" )
144+ return visualizer
130145 except OSError as e :
131146 # Handle low-level system errors (e.g., graphics context failures)
132147 raise RuntimeError (
133- f"Visualizer plugin failed to initialize: { e } . "
148+ f"Visualizer plugin failed to initialize due to system error : { e } . "
134149 "This may indicate missing graphics drivers, OpenGL issues, or "
135150 "incompatible system configuration. Try building with different options "
136151 "or check system requirements."
137152 )
138-
139- return visualizer
140153
141154def create_visualizer_with_antialiasing (width : int , height : int , antialiasing_samples : int , headless : bool = False ) -> Optional [ctypes .POINTER (UVisualizer )]:
142155 """
@@ -161,18 +174,23 @@ def create_visualizer_with_antialiasing(width: int, height: int, antialiasing_sa
161174 "Rebuild with visualizer plugin enabled."
162175 )
163176
164- visualizer = helios_lib .createVisualizerWithAntialiasing (
165- ctypes .c_uint32 (width ),
166- ctypes .c_uint32 (height ),
167- ctypes .c_uint32 (antialiasing_samples ),
168- ctypes .c_bool (headless )
169- )
170- _check_for_helios_error ()
171-
172- if not visualizer :
173- raise RuntimeError ("Failed to create Visualizer with antialiasing" )
174-
175- return visualizer
177+ try :
178+ # The errcheck callback will handle error checking and null pointer validation
179+ visualizer = helios_lib .createVisualizerWithAntialiasing (
180+ ctypes .c_uint32 (width ),
181+ ctypes .c_uint32 (height ),
182+ ctypes .c_uint32 (antialiasing_samples ),
183+ ctypes .c_bool (headless )
184+ )
185+ return visualizer
186+ except OSError as e :
187+ # Handle low-level system errors (e.g., graphics context failures)
188+ raise RuntimeError (
189+ f"Visualizer plugin failed to initialize due to system error: { e } . "
190+ "This may indicate missing graphics drivers, OpenGL issues, or "
191+ "incompatible system configuration. Try building with different options "
192+ "or check system requirements."
193+ )
176194
177195def destroy_visualizer (visualizer : ctypes .POINTER (UVisualizer )) -> None :
178196 """
0 commit comments