Skip to content

Commit 9cb1776

Browse files
committed
Throw from Client::async_get_result if the goal handle was invalidated due to a failed result request
Propagate error message from a failed result request. Also set result awareness to false if the result request fails so the user can also check before being hit with an exception. Signed-off-by: Jacob Perron <jacob@openrobotics.org>
1 parent 68cd6e9 commit 9cb1776

4 files changed

Lines changed: 31 additions & 9 deletions

File tree

rclcpp_action/include/rclcpp_action/client.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ class Client : public ClientBase
407407
/// Asynchronously get the result for an active goal.
408408
/**
409409
* \throws exceptions::UnknownGoalHandleError If the goal unknown or already reached a terminal
410-
* state.
410+
* state, or if there was an error requesting the result.
411411
* \param[in] goal_handle The goal handle for which to get the result.
412412
* \param[in] result_callback Optional callback that is called when the result is received.
413413
* \return A future that is set to the goal result when the goal is finished.
@@ -421,6 +421,11 @@ class Client : public ClientBase
421421
if (goal_handles_.count(goal_handle->get_goal_id()) == 0) {
422422
throw exceptions::UnknownGoalHandleError();
423423
}
424+
if (goal_handle->is_invalidated()) {
425+
// This case can happen if there was a failure to send the result request
426+
// during the goal response callback
427+
throw goal_handle->invalidate_exception_;
428+
}
424429
if (result_callback) {
425430
// This will override any previously registered callback
426431
goal_handle->set_result_callback(result_callback);
@@ -511,7 +516,7 @@ class Client : public ClientBase
511516
while (it != goal_handles_.end()) {
512517
typename GoalHandle::SharedPtr goal_handle = it->second.lock();
513518
if (goal_handle) {
514-
goal_handle->invalidate();
519+
goal_handle->invalidate(exceptions::UnawareGoalHandleError());
515520
}
516521
it = goal_handles_.erase(it);
517522
}
@@ -642,9 +647,9 @@ class Client : public ClientBase
642647
std::lock_guard<std::mutex> lock(goal_handles_mutex_);
643648
goal_handles_.erase(goal_handle->get_goal_id());
644649
});
645-
} catch (rclcpp::exceptions::RCLError &) {
650+
} catch (rclcpp::exceptions::RCLError & ex) {
646651
// This will cause an exception when the user tries to access the result
647-
goal_handle->invalidate();
652+
goal_handle->invalidate(exceptions::UnawareGoalHandleError(ex.message));
648653
}
649654
}
650655

rclcpp_action/include/rclcpp_action/client_goal_handle.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <memory>
2727
#include <mutex>
2828

29+
#include "rclcpp_action/exceptions.hpp"
2930
#include "rclcpp_action/types.hpp"
3031
#include "rclcpp_action/visibility_control.hpp"
3132

@@ -145,10 +146,15 @@ class ClientGoalHandle
145146
set_result(const WrappedResult & wrapped_result);
146147

147148
void
148-
invalidate();
149+
invalidate(const exceptions::UnawareGoalHandleError & ex);
150+
151+
bool
152+
is_invalidated() const;
149153

150154
GoalInfo info_;
151155

156+
std::exception_ptr invalidate_exception_{nullptr};
157+
152158
bool is_result_aware_{false};
153159
std::promise<WrappedResult> result_promise_;
154160
std::shared_future<WrappedResult> result_future_;

rclcpp_action/include/rclcpp_action/client_goal_handle_impl.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,20 @@ ClientGoalHandle<ActionT>::set_result_awareness(bool awareness)
138138

139139
template<typename ActionT>
140140
void
141-
ClientGoalHandle<ActionT>::invalidate()
141+
ClientGoalHandle<ActionT>::invalidate(const exceptions::UnawareGoalHandleError & ex)
142142
{
143143
std::lock_guard<std::mutex> guard(handle_mutex_);
144+
is_result_aware_ = false;
145+
invalidate_exception_ = std::make_exception_ptr(ex);
144146
status_ = GoalStatus::STATUS_UNKNOWN;
145-
result_promise_.set_exception(std::make_exception_ptr(exceptions::UnawareGoalHandleError()));
147+
result_promise_.set_exception(invalidate_exception_);
148+
}
149+
150+
template<typename ActionT>
151+
bool
152+
ClientGoalHandle<ActionT>::is_invalidated() const
153+
{
154+
return invalidate_exception_ != nullptr;
146155
}
147156

148157
template<typename ActionT>

rclcpp_action/include/rclcpp_action/exceptions.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define RCLCPP_ACTION__EXCEPTIONS_HPP_
1717

1818
#include <stdexcept>
19+
#include <string>
1920

2021
namespace rclcpp_action
2122
{
@@ -33,8 +34,9 @@ class UnknownGoalHandleError : public std::invalid_argument
3334
class UnawareGoalHandleError : public std::runtime_error
3435
{
3536
public:
36-
UnawareGoalHandleError()
37-
: std::runtime_error("Goal handle is not tracking the goal result.")
37+
UnawareGoalHandleError(
38+
const std::string & message = "Goal handle is not tracking the goal result.")
39+
: std::runtime_error(message)
3840
{
3941
}
4042
};

0 commit comments

Comments
 (0)