[ROS2] Best practice for catching all exceptions for logging
I am creating a robot with ROS2 foxy that is in the field, and therefore not monitored all the time.
To help with debugging any eventual bugs/crashes that are unaccounted for, I was thinking of logging any tracebacks that occur.
There are two approaches that I am considering:
Catch and except rclpy.spin
original post code
import rclpy
import traceback
from .example_node import NodeClass
def main(args=None):
rclpy.init(args=args)
node_class = NodeClass()
try:
rclpy.spin(node_class)
except Exception:
node_class.get_logger().error(traceback.format_exc())
finally:
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
node_class.destroy_node()
rclpy.shutdown()
update post code after @Geoff comment
import rclpy
import traceback
from .example_node import NodeClass
def main(args=None):
rclpy.init(args=args)
traceback_logger = rclpy.logging.get_logger('node_class_traceback_logger')
try:
node_class = NodeClass()
rclpy.spin(node_class)
except Exception as exception:
traceback_logger.error(traceback.format_exc())
raise exception
finally:
# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
node_class.destroy_node()
rclpy.shutdown()
Create a custom logger in launch file
from the example launch found here, a custom event handler can be created. This could potentially catch tracebacks.
# Setup a custom event handler for all stdout/stderr from processes.
# Later, this will be a configurable, but always present, extension to the LaunchService.
def on_output(event: launch.Event) -> None:
for line in event.text.decode().splitlines():
print('[{}] {}'.format(
cast(launch.events.process.ProcessIO, event).process_name, line))
ld.add_action(launch.actions.RegisterEventHandler(launch.event_handlers.OnProcessIO(
# this is the action ^ and this, the event handler ^
on_stdout=on_output,
on_stderr=on_output,
)))
Which of these would be considered better practice? Or is there a better approach builtin ROS2?
Thanks in advance!