ROS 2 rclcpp + rcl - rolling  rolling-a919a6e5
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  rcl_reset_error();
98 }
99 
100 RCLError::RCLError(
101  rcl_ret_t ret,
102  const rcl_error_state_t * error_state,
103  const std::string & prefix)
104 : RCLError(RCLErrorBase(ret, error_state), prefix)
105 {}
106 
107 RCLError::RCLError(
108  const RCLErrorBase & base_exc,
109  const std::string & prefix)
110 : RCLErrorBase(base_exc), std::runtime_error(prefix + base_exc.formatted_message)
111 {}
112 
113 RCLBadAlloc::RCLBadAlloc(rcl_ret_t ret, const rcl_error_state_t * error_state)
114 : RCLBadAlloc(RCLErrorBase(ret, error_state))
115 {}
116 
117 RCLBadAlloc::RCLBadAlloc(const RCLErrorBase & base_exc)
118 : RCLErrorBase(base_exc), std::bad_alloc()
119 {}
120 
121 RCLInvalidArgument::RCLInvalidArgument(
122  rcl_ret_t ret,
123  const rcl_error_state_t * error_state,
124  const std::string & prefix)
125 : RCLInvalidArgument(RCLErrorBase(ret, error_state), prefix)
126 {}
127 
128 RCLInvalidArgument::RCLInvalidArgument(
129  const RCLErrorBase & base_exc,
130  const std::string & prefix)
131 : RCLErrorBase(base_exc), std::invalid_argument(prefix + base_exc.formatted_message)
132 {}
133 
134 RCLInvalidROSArgsError::RCLInvalidROSArgsError(
135  rcl_ret_t ret,
136  const rcl_error_state_t * error_state,
137  const std::string & prefix)
138 : RCLInvalidROSArgsError(RCLErrorBase(ret, error_state), prefix)
139 {}
140 
141 RCLInvalidROSArgsError::RCLInvalidROSArgsError(
142  const RCLErrorBase & base_exc,
143  const std::string & prefix)
144 : RCLErrorBase(base_exc), std::runtime_error(prefix + base_exc.formatted_message)
145 {}
146 
147 } // namespace exceptions
148 } // 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:111
#define RCL_RET_OK
Success return code.
Definition: types.h:27
#define RCL_RET_BAD_ALLOC
Failed to allocate memory return code.
Definition: types.h:33
#define RCL_RET_INVALID_ARGUMENT
Invalid argument return code.
Definition: types.h:35
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
Definition: types.h:24