iceoryx_doc  1.0.1
error_handling.hpp
1 // Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
2 // Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // SPDX-License-Identifier: Apache-2.0
17 #ifndef IOX_UTILS_ERROR_HANDLING_ERROR_HANDLING_HPP
18 #define IOX_UTILS_ERROR_HANDLING_ERROR_HANDLING_HPP
19 
20 #include "iceoryx_utils/cxx/generic_raii.hpp"
21 #include "iceoryx_utils/cxx/vector.hpp"
22 
23 #include <assert.h>
24 #include <functional>
25 #include <iostream>
26 #include <mutex>
27 
28 namespace iox
29 {
30 // clang-format off
31 #define ICEORYX_ERRORS(error) \
32  error(NO_ERROR)\
33  error(FILEREADER__FAILED_TO_OPEN_FILE) \
34  error(POSH__ROUDI_PROCESS_SHUTDOWN_FAILED) \
35  error(POSH__ROUDI_PROCESS_SEND_VIA_IPC_CHANNEL_FAILED)\
36  error(POSH__RUNTIME_FACTORY_IS_NOT_SET) \
37  error(POSH__RUNTIME_IS_CREATED_MULTIPLE_TIMES) \
38  error(POSH__RUNTIME_PUBLISHER_PORT_NOT_UNIQUE) \
39  error(POSH__RUNTIME_PUBLISHER_PORT_CREATION_UNDEFINED_BEHAVIOR) \
40  error(POSH__RUNTIME_SUBSCRIBER_PORT_CREATION_UNDEFINED_BEHAVIOR) \
41  error(POSH__RUNTIME_ROUDI_PUBLISHER_LIST_FULL) \
42  error(POSH__RUNTIME_ROUDI_SUBSCRIBER_LIST_FULL) \
43  error(POSH__RUNTIME_ROUDI_CONDITION_VARIABLE_LIST_FULL) \
44  error(POSH__RUNTIME_ROUDI_EVENT_VARIABLE_LIST_FULL) \
45  error(POSH__RUNTIME_ROUDI_REQUEST_PUBLISHER_WRONG_IPC_MESSAGE_RESPONSE) \
46  error(POSH__RUNTIME_ROUDI_REQUEST_SUBSCRIBER_WRONG_IPC_MESSAGE_RESPONSE) \
47  error(POSH__RUNTIME_ROUDI_REQUEST_CONDITION_VARIABLE_WRONG_IPC_MESSAGE_RESPONSE) \
48  error(POSH__RUNTIME_ROUDI_REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE) \
49  error(POSH__RUNTIME_ROUDI_GET_MW_INTERFACE_WRONG_IPC_MESSAGE_RESPONSE) \
50  error(POSH__RUNTIME_ROUDI_CREATE_NODE_WRONG_IPC_MESSAGE_RESPONSE) \
51  error(POSH__RUNTIME_ROUDI_GET_MW_APPLICATION_WRONG_IPC_MESSAGE_RESPONSE) \
52  error(POSH__RUNTIME_ROUDI_CONDITION_VARIABLE_CREATION_UNDEFINED_BEHAVIOR) \
53  error(POSH__RUNTIME_ROUDI_EVENT_VARIABLE_CREATION_UNDEFINED_BEHAVIOR) \
54  error(POSH__RUNTIME_APP_WITH_SAME_RUNTIME_NAME_STILL_RUNNING) \
55  error(POSH__RUNTIME_NO_WRITABLE_SHM_SEGMENT) \
56  error(POSH__PORT_MANAGER_PUBLISHERPORT_NOT_UNIQUE) \
57  error(POSH__MEMPOOL_POSSIBLE_DOUBLE_FREE) \
58  error(POSH__RECEIVERPORT_DELIVERYFIFO_OVERFLOW) \
59  error(POSH__SENDERPORT_SAMPLE_SIZE_CHANGED_FOR_ACTIVE_PORT) \
60  error(POSH__SENDERPORT_ACTIVATE_FIELD_WITHOUT_DATA) \
61  error(POSH__SENDERPORT_FIELD_SUBSCRIBE_WITHOUT_DATA) \
62  error(POSH__SENDERPORT_ACTIVATE_FIELD_WHEN_LATCHED_TOPIC_ACTIVATED) \
63  error(POSH__SENDERPORT_ALLOCATE_FAILED) \
64  error(POSH__SENDERPORT_SUBSCRIBER_LIST_OVERFLOW) \
65  error(POSH__PUBLISHING_EMPTY_SAMPLE) \
66  error(POSH__SHM_APP_BASEADDRESS_VIOLATES_SPECIFICATION) \
67  error(POSH__SHM_APP_SEGMENT_BASEADDRESS_VIOLATES_SPECIFICATION) \
68  error(POSH__SHM_APP_MAPP_ERR) \
69  error(POSH__SHM_APP_SEGMENT_MAPP_ERR) \
70  error(POSH__SHM_APP_SEGMENT_COUNT_OVERFLOW) \
71  error(POSH__INTERFACEPORT_CAPRO_MESSAGE_DISMISSED) \
72  error(POSH__SERVICE_DISCOVERY_INSTANCE_CONTAINER_OVERFLOW) \
73  error(POSH__SERVICE_DISCOVERY_FIND_SERVICE_CALLBACKS_CONTAINER_OVERFLOW) \
74  error(POPO__APPLICATION_PORT_QUEUE_OVERFLOW) \
75  error(POPO__BASE_SUBSCRIBER_OVERRIDING_WITH_EVENT_SINCE_HAS_DATA_OR_DATA_RECEIVED_ALREADY_ATTACHED) \
76  error(POPO__BASE_SUBSCRIBER_OVERRIDING_WITH_STATE_SINCE_HAS_DATA_OR_DATA_RECEIVED_ALREADY_ATTACHED) \
77  error(POPO__CHUNK_QUEUE_POPPER_CHUNK_WITH_INCOMPATIBLE_CHUNK_HEADER_VERSION) \
78  error(POPO__CHUNK_DISTRIBUTOR_OVERFLOW_OF_QUEUE_CONTAINER) \
79  error(POPO__CHUNK_DISTRIBUTOR_CLEANUP_DEADLOCK_BECAUSE_BAD_APPLICATION_TERMINATION) \
80  error(POPO__CHUNK_SENDER_INVALID_CHUNK_TO_FREE_FROM_USER) \
81  error(POPO__CHUNK_SENDER_INVALID_CHUNK_TO_SEND_FROM_USER) \
82  error(POPO__CHUNK_RECEIVER_INVALID_CHUNK_TO_RELEASE_FROM_USER) \
83  error(POPO__CHUNK_LOCKING_ERROR) \
84  error(POPO__CHUNK_UNLOCKING_ERROR) \
85  error(POPO__CAPRO_PROTOCOL_ERROR) \
86  error(POPO__CONDITION_VARIABLE_DATA_FAILED_TO_CREATE_SEMAPHORE) \
87  error(POPO__CONDITION_LISTENER_SEMAPHORE_CORRUPTED_IN_WAS_TRIGGERED) \
88  error(POPO__CONDITION_LISTENER_SEMAPHORE_CORRUPTED_IN_WAIT) \
89  error(POPO__CONDITION_LISTENER_SEMAPHORE_CORRUPTED_IN_TIMED_WAIT) \
90  error(POPO__CONDITION_LISTENER_SEMAPHORE_CORRUPTED_IN_RESET) \
91  error(POPO__CONDITION_LISTENER_SEMAPHORE_CORRUPTED_IN_DESTROY) \
92  error(POPO__CONDITION_NOTIFIER_INDEX_TOO_LARGE) \
93  error(POPO__CONDITION_NOTIFIER_SEMAPHORE_CORRUPT_IN_NOTIFY) \
94  error(POPO__NOTIFICATION_INFO_TYPE_INCONSISTENCY_IN_GET_ORIGIN) \
95  error(POPO__TRIGGER_INVALID_RESET_CALLBACK) \
96  error(POPO__TRIGGER_INVALID_HAS_TRIGGERED_CALLBACK) \
97  error(POPO__TRIGGER_HANDLE_INVALID_RESET_CALLBACK) \
98  error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_NO_DEFINED_UNIQUE_ID) \
99  error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_ALREADY_DEFINED_UNIQUE_ID) \
100  error(POPO__TYPED_UNIQUE_ID_OVERFLOW) \
101  error(POPO__WAITSET_COULD_NOT_DETACH_CONDITION) \
102  error(MEPOO__MEMPOOL_CONFIG_MUST_BE_ORDERED_BY_INCREASING_SIZE) \
103  error(MEPOO__MEMPOOL_GETCHUNK_CHUNK_WITHOUT_MEMPOOL) \
104  error(MEPOO__MEMPOOL_GETCHUNK_CHUNK_IS_TOO_LARGE) \
105  error(MEPOO__MEMPOOL_GETCHUNK_POOL_IS_RUNNING_OUT_OF_CHUNKS) \
106  error(MEPOO__MEMPOOL_CHUNKSIZE_MUST_BE_MULTIPLE_OF_CHUNK_MEMORY_ALIGNMENT) \
107  error(MEPOO__MEMPOOL_ADDMEMPOOL_AFTER_GENERATECHUNKMANAGEMENTPOOL) \
108  error(MEPOO__TYPED_MEMPOOL_HAS_INCONSISTENT_STATE) \
109  error(MEPOO__TYPED_MEMPOOL_MANAGEMENT_SEGMENT_IS_BROKEN) \
110  error(MEPOO__USER_WITH_MORE_THAN_ONE_WRITE_SEGMENT) \
111  error(MEPOO__SEGMENT_COULD_NOT_APPLY_POSIX_RIGHTS_TO_SHARED_MEMORY) \
112  error(MEPOO__SEGMENT_UNABLE_TO_CREATE_SHARED_MEMORY_OBJECT) \
113  error(MEPOO__INTROSPECTION_CONTAINER_FULL) \
114  error(MEPOO__CANNOT_ALLOCATE_CHUNK) \
115  error(PORT_POOL__PUBLISHERLIST_OVERFLOW) \
116  error(PORT_POOL__SUBSCRIBERLIST_OVERFLOW) \
117  error(PORT_POOL__INTERFACELIST_OVERFLOW) \
118  error(PORT_POOL__APPLICATIONLIST_OVERFLOW) \
119  error(PORT_POOL__NODELIST_OVERFLOW) \
120  error(PORT_POOL__CONDITION_VARIABLE_LIST_OVERFLOW) \
121  error(PORT_POOL__EVENT_VARIABLE_LIST_OVERFLOW) \
122  error(PORT_MANAGER__PORT_POOL_UNAVAILABLE) \
123  error(PORT_MANAGER__INTROSPECTION_MEMORY_MANAGER_UNAVAILABLE) \
124  error(PORT_MANAGER__HANDLE_PUBLISHER_PORTS_INVALID_CAPRO_MESSAGE) \
125  error(PORT_MANAGER__HANDLE_SUBSCRIBER_PORTS_INVALID_CAPRO_MESSAGE) \
126  error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONPORTSERVICE) \
127  error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONPORTTHROUGHPUTSERVICE) \
128  error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONCHANGINGDATASERVICE) \
129  error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTION_SENDER_PORT) \
130  error(ROUDI_COMPONENTS__SHARED_MEMORY_UNAVAILABLE) \
131  error(ROUDI_APP__FAILED_TO_CREATE_SEMAPHORE) \
132  error(ROUDI_APP__FAILED_TO_UNLOCK_SEMAPHORE_IN_SIG_HANDLER) \
133  error(ROUDI__DEFAULT_ROUDI_MEMORY_FAILED_TO_ADD_SEGMENT_MANAGER_MEMORY_BLOCK) \
134  error(ROUDI__DEFAULT_ROUDI_MEMORY_FAILED_TO_ADD_INTROSPECTION_MEMORY_BLOCK) \
135  error(ICEORYX_ROUDI_MEMORY_MANAGER__COULD_NOT_ACQUIRE_FILE_LOCK) \
136  error(ICEORYX_ROUDI_MEMORY_MANAGER__ROUDI_STILL_RUNNING) \
137  error(ICEORYX_ROUDI_MEMORY_MANAGER__FAILED_TO_ADD_PORTPOOL_MEMORY_BLOCK) \
138  error(ICEORYX_ROUDI_MEMORY_MANAGER__FAILED_TO_ADD_MANAGEMENT_MEMORY_BLOCK) \
139  error(MQ_UNKNOWN_MSG) \
140  error(MQ_INVALID_MSG) \
141  error(IPC_INTERFACE__UNABLE_TO_CREATE_APPLICATION_CHANNEL) \
142  error(IPC_INTERFACE__REG_ROUDI_NOT_AVAILABLE) \
143  error(IPC_INTERFACE__REG_UNABLE_TO_WRITE_TO_ROUDI_CHANNEL) \
144  error(IPC_INTERFACE__REG_ACK_INVALIG_NUMBER_OF_PARAMS) \
145  error(IPC_INTERFACE__REG_ACK_NO_RESPONSE) \
146  error(IPC_INTERFACE__CHECK_MQ_MAPS_TO_FILE) \
147  error(IPC_INTERFACE__APP_WITH_SAME_NAME_STILL_RUNNING) \
148  error(IPC_INTERFACE__COULD_NOT_ACQUIRE_FILE_LOCK) \
149  error(POSIX_WRAPPER__FAILED_TO_CREATE_SEMAPHORE) \
150  error(POSIX_TIMER__FIRED_TIMER_BUT_STATE_IS_INVALID) \
151  error(POSIX_TIMER__TIMERPOOL_OVERFLOW) \
152  error(POSIX_TIMER__INCONSISTENT_STATE) \
153  error(POSIX_TIMER__CALLBACK_RUNTIME_EXCEEDS_RETRIGGER_TIME) \
154  error(BINDING_C__UNDEFINED_STATE_IN_IOX_QUEUE_FULL_POLICY) \
155  error(BINDING_C__UNDEFINED_STATE_IN_IOX_SUBSCRIBER_TOO_SLOW_POLICY) \
156  error(BINDING_C__PUBLISHER_OPTIONS_NOT_INITIALIZED) \
157  error(BINDING_C__SUBSCRIBER_OPTIONS_NOT_INITIALIZED) \
158  error(BINDING_C__C2CPP_ENUM_TRANSLATION_INVALID_SUBSCRIBER_EVENT_VALUE) \
159  error(BINDING_C__C2CPP_ENUM_TRANSLATION_INVALID_SUBSCRIBER_STATE_VALUE)
160 
161 // clang-format on
162 
163 // DO NOT TOUCH START, you can doodle around with the lines above!!!
164 #define CREATE_ICEORYX_ERROR_ENUM(name) k##name,
165 #define CREATE_ICEORYX_ERROR_STRING(name) #name,
166 
167 enum class Error : uint32_t
168 {
169  ICEORYX_ERRORS(CREATE_ICEORYX_ERROR_ENUM)
170 };
171 
188 enum class ErrorLevel : uint32_t
189 {
191  FATAL,
193  SEVERE,
195  MODERATE
196 };
197 
198 using HandlerFunction = std::function<void(const Error error, const std::function<void()>, const ErrorLevel)>;
199 
204 {
205  friend void errorHandler(const Error error, const std::function<void()> errorCallBack, const ErrorLevel level);
206 
207  public:
208  static cxx::GenericRAII SetTemporaryErrorHandler(const HandlerFunction& newHandler);
209 
210  static const char* ToString(const Error error);
211 
212  protected:
213  static void ReactOnErrorLevel(const ErrorLevel level, const char* errorText);
214 
215  private:
216  static void DefaultHandler(const Error error,
217  const std::function<void()> errorCallBack,
218  const ErrorLevel level = ErrorLevel::FATAL);
219 
220  static const char* errorNames[];
221  static iox::HandlerFunction handler;
224  static std::mutex handler_mutex;
225 };
226 
264 void errorHandler(const Error error,
265  const std::function<void()> errorCallBack = std::function<void()>(),
266  const ErrorLevel level = ErrorLevel::FATAL);
267 } // namespace iox
268 
269 #endif // IOX_UTILS_ERROR_HANDLING_ERROR_HANDLING_HPP
This handler is needed for unit testing, special debugging cases and other corner cases where we'd li...
Definition: error_handling.hpp:204
friend void errorHandler(const Error error, const std::function< void()> errorCallBack, const ErrorLevel level)
Howto use the error handler correctly 1.) If the error you would like to handle is not listed in ICEO...
The GenericRAII class is a simple helper class to apply the C++ RAII idiom quickly....
Definition: generic_raii.hpp:46
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:28
void errorHandler(const Error error, const std::function< void()> errorCallBack=std::function< void()>(), const ErrorLevel level=ErrorLevel::FATAL)
Howto use the error handler correctly 1.) If the error you would like to handle is not listed in ICEO...
ErrorLevel
the available error levels FATAL
Definition: error_handling.hpp:189
@ FATAL
Log error entry + Assert + terminate.
@ SEVERE
warning log entry + Assert
@ MODERATE
warning log entry