ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
exceptions.cpp
1 // Copyright 2016 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "rclcpp/exceptions.hpp"
16 
17 #include <cstdio>
18 #include <functional>
19 #include <string>
20 #include <vector>
21 
22 using namespace std::string_literals;
23 
24 namespace rclcpp
25 {
26 namespace exceptions
27 {
28 
29 std::string
30 NameValidationError::format_error(
31  const char * name_type,
32  const char * name,
33  const char * error_msg,
34  size_t invalid_index)
35 {
36  std::string msg = "";
37  msg += "Invalid "s + name_type + ": " + error_msg + ":\n";
38  msg += " '"s + name + "'\n";
39  msg += " "s + std::string(invalid_index, ' ') + "^\n";
40  return msg;
41 }
42 
43 std::exception_ptr
44 from_rcl_error(
45  rcl_ret_t ret,
46  const std::string & prefix,
47  const rcl_error_state_t * error_state,
48  void (* reset_error)())
49 {
50  if (RCL_RET_OK == ret) {
51  throw std::invalid_argument("ret is RCL_RET_OK");
52  }
53  if (!error_state) {
54  error_state = rcl_get_error_state();
55  }
56  if (!error_state) {
57  throw std::runtime_error("rcl error state is not set");
58  }
59  std::string formatted_prefix = prefix;
60  if (!prefix.empty()) {
61  formatted_prefix += ": ";
62  }
63  RCLErrorBase base_exc(ret, error_state);
64  if (reset_error) {
65  reset_error();
66  }
67  switch (ret) {
68  case RCL_RET_BAD_ALLOC:
69  return std::make_exception_ptr(RCLBadAlloc(base_exc));
71  return std::make_exception_ptr(RCLInvalidArgument(base_exc, formatted_prefix));
73  return std::make_exception_ptr(RCLInvalidROSArgsError(base_exc, formatted_prefix));
74  default:
75  return std::make_exception_ptr(RCLError(base_exc, formatted_prefix));
76  }
77 }
78 
79 void
80 throw_from_rcl_error(
81  rcl_ret_t ret,
82  const std::string & prefix,
83  const rcl_error_state_t * error_state,
84  void (* reset_error)())
85 {
86  // We expect this to either throw a standard error,
87  // or to generate an error pointer (which is caught
88  // in err, and immediately thrown)
89  auto err = from_rcl_error(ret, prefix, error_state, reset_error);
90  std::rethrow_exception(err);
91 }
92 
93 RCLErrorBase::RCLErrorBase(rcl_ret_t ret, const rcl_error_state_t * error_state)
94 : ret(ret), message(error_state->message), file(error_state->file), line(error_state->line_number),
95  formatted_message(rcl_get_error_string().str)
96 {}
97 
98 RCLError::RCLError(
99  rcl_ret_t ret,
100  const rcl_error_state_t * error_state,
101  const std::string & prefix)
102 : RCLError(RCLErrorBase(ret, error_state), prefix)
103 {}
104 
105 RCLError::RCLError(
106  const RCLErrorBase & base_exc,
107  const std::string & prefix)
108 : RCLErrorBase(base_exc), std::runtime_error(prefix + base_exc.formatted_message)
109 {}
110 
111 RCLBadAlloc::RCLBadAlloc(rcl_ret_t ret, const rcl_error_state_t * error_state)
112 : RCLBadAlloc(RCLErrorBase(ret, error_state))
113 {}
114 
115 RCLBadAlloc::RCLBadAlloc(const RCLErrorBase & base_exc)
116 : RCLErrorBase(base_exc), std::bad_alloc()
117 {}
118 
119 RCLInvalidArgument::RCLInvalidArgument(
120  rcl_ret_t ret,
121  const rcl_error_state_t * error_state,
122  const std::string & prefix)
123 : RCLInvalidArgument(RCLErrorBase(ret, error_state), prefix)
124 {}
125 
126 RCLInvalidArgument::RCLInvalidArgument(
127  const RCLErrorBase & base_exc,
128  const std::string & prefix)
129 : RCLErrorBase(base_exc), std::invalid_argument(prefix + base_exc.formatted_message)
130 {}
131 
132 RCLInvalidROSArgsError::RCLInvalidROSArgsError(
133  rcl_ret_t ret,
134  const rcl_error_state_t * error_state,
135  const std::string & prefix)
136 : RCLInvalidROSArgsError(RCLErrorBase(ret, error_state), prefix)
137 {}
138 
139 RCLInvalidROSArgsError::RCLInvalidROSArgsError(
140  const RCLErrorBase & base_exc,
141  const std::string & prefix)
142 : RCLErrorBase(base_exc), std::runtime_error(prefix + base_exc.formatted_message)
143 {}
144 
145 } // namespace exceptions
146 } // namespace rclcpp
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
#define RCL_RET_INVALID_ROS_ARGS
Found invalid ros argument while parsing.
Definition: types.h:108
#define RCL_RET_OK
Success return code.
Definition: types.h:26
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:32
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:34
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:23