-
Notifications
You must be signed in to change notification settings - Fork 560
Don't let malformed set_parameters requests crash the node #3256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rolling
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ | |
| #include "rclcpp/parameter_service.hpp" | ||
|
|
||
| #include <algorithm> | ||
| #include <exception> | ||
| #include <memory> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
@@ -90,7 +91,7 @@ ParameterService::ParameterService( | |
| try { | ||
| result = node_params->set_parameters_atomically( | ||
| {rclcpp::Parameter::from_parameter_msg(p)}); | ||
| } catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) { | ||
| } catch (const std::exception & ex) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: could scope this to just a handful of relevant exceptions
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but then as soon as a new exception is added you can introduce the same crash. What does scoping add here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See comment here #3257 (comment)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Catchalls are considered back practice as you might also catch exceptions that were not meant to be catched.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that backporting is desirable, what is the best type to use in this case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Totally agreed but arguably completely missed exceptions also bad practice. I think catching broadly here fixes the current issue but to properly fix this with best practices, all |
||
| RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to set parameter: %s", ex.what()); | ||
| result.successful = false; | ||
| result.reason = ex.what(); | ||
|
|
@@ -108,21 +109,26 @@ ParameterService::ParameterService( | |
| const std::shared_ptr<rcl_interfaces::srv::SetParametersAtomically::Request> & request, | ||
| std::shared_ptr<rcl_interfaces::srv::SetParametersAtomically::Response> response) | ||
| { | ||
| std::vector<rclcpp::Parameter> pvariants; | ||
| std::transform( | ||
| request->parameters.cbegin(), request->parameters.cend(), | ||
| std::back_inserter(pvariants), | ||
| [](const rcl_interfaces::msg::Parameter & p) { | ||
| return rclcpp::Parameter::from_parameter_msg(p); | ||
| }); | ||
| try { | ||
| std::vector<rclcpp::Parameter> pvariants; | ||
| std::transform( | ||
| request->parameters.cbegin(), request->parameters.cend(), | ||
| std::back_inserter(pvariants), | ||
| [](const rcl_interfaces::msg::Parameter & p) { | ||
| return rclcpp::Parameter::from_parameter_msg(p); | ||
| }); | ||
| auto result = node_params->set_parameters_atomically(pvariants); | ||
| response->result = result; | ||
| } catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) { | ||
| RCLCPP_WARN( | ||
| rclcpp::get_logger("rclcpp"), "Failed to set parameters atomically: %s", ex.what()); | ||
| response->result.successful = false; | ||
| response->result.reason = "One or more parameters were not declared before setting"; | ||
| } catch (const std::exception & ex) { | ||
| RCLCPP_WARN( | ||
| rclcpp::get_logger("rclcpp"), "Failed to set parameters atomically: %s", ex.what()); | ||
| response->result.successful = false; | ||
| response->result.reason = ex.what(); | ||
| } | ||
| }, | ||
| qos_profile, nullptr); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we should kee this specific exception to distinguish from the following generic exception.