ComIn 0.5.1
ICON Community Interface
Loading...
Searching...
No Matches
comin_error.cpp
Go to the documentation of this file.
1// @file comin_error.cpp
2// @brief Error handling functions
3//
4// @authors 01/2026 :: ICON Community Interface <comin@icon-model.org>
5//
6// SPDX-License-Identifier: BSD-3-Clause
7//
8// See LICENSES for license information.
9// Where software is supplied by third parties, it is indicated in the
10// headers of the routines.
11
12#include "comin_logging.hpp"
13#include "comin_state.hpp"
14#include "comin_util.hpp"
15
16#include <mpi.h>
17
18#include <algorithm>
19#include <array>
20#include <string_view>
21#include <tuple>
22
23static_assert(sizeof(t_comin_error_code) == sizeof(int),
24 "The underlying type of t_comin_error_code must be int for "
25 "Fortran interoperability. Recompile with "
26 "-fno-short-enums or similar.");
27
28namespace {
29using namespace std::string_view_literals;
30
31constexpr auto error_strings = comin::to_array<
32 std::tuple<t_comin_error_code, std::string_view>>({
33 {COMIN_SUCCESS, "Success"sv},
34 {COMIN_INFO, "Info"sv},
35 {COMIN_WARNING, "Warning"sv},
36 {COMIN_ERROR_STATUS, "Error"sv},
38 "Callbacks cannot be registered after primary constructor."sv},
40 "Callback registration could not be completed."sv},
41 {COMIN_ERROR_CALLBACK_EP_ID_UNKNOWN, "Unknown ID for entry point."sv},
43 "Unable to set descriptive data function: glb2loc. Function not associated."sv},
45 "Unable to clean up descriptive data structure (finalize)."sv},
47 "Cannot set metadata outside primary constructor."sv},
48 {COMIN_ERROR_METADATA_KEY_NOT_FOUND, "Metadata key not found."sv},
50 "Unable to get metadata inside primary constructor."sv},
51 {COMIN_ERROR_SETUP_FINALIZE, "Setup finalized failed."sv},
53 "ComIn is already initilized."sv},
55 "The host model error handler procedure cannot be found."sv},
57 "Error handler not set (setup check)."sv},
59 "Precision test failed (setup check)."sv},
61 "Variables cannot be requested after primary constructor."sv},
63 "Requested variable already exists and is exclusive."sv},
65 "Requested exclusive variable already exists."sv},
66 {COMIN_ERROR_VAR_DESCRIPTOR_NOT_FOUND, "var_descriptor not found."sv},
67 {COMIN_ERROR_VAR_ITEM_NOT_ASSOCIATED, "var_item not associated."sv},
68 {COMIN_ERROR_FIELD_NOT_ALLOCATED, "Field not allocated."sv},
69 {COMIN_ERROR_POINTER_NOT_ASSOCIATED, "Pointer not associated."sv},
71 "Tracers need to be requested for all domains (id=-1)."sv},
73 "Sync device memory callback not set (setup check)."sv},
75 "Sync halo callback not set (setup check)."sv},
77 "Cannot get variable outside of secondary constructor."sv},
78 {COMIN_ERROR_VAR_GET_NO_DEVICE, "No device available."sv},
79 {COMIN_ERROR_VAR_GET_VARIABLE_NOT_FOUND, "Cannot find variable."sv},
81 "Cannot halo sync a container."sv},
83 "Cannot halo sync an irregular variable."sv},
85 "Can only halo sync vars on 2D or 3D vertical grid."sv},
87 "Metadata type does not match access function."sv},
89 "Wrong type used requesting the pointer of a variable."sv},
90 {COMIN_ERROR_INDEX_OUT_OF_BOUNDS, "Index out of bounds."sv},
91 {COMIN_ERROR_DESCRDATA_TIMESTEPLENGTH_NOT_SET, "timesteplength not set"},
92 {COMIN_ERROR_FATAL, "Fatal error."sv},
93});
94} // namespace
95
96namespace comin::error {
97std::string_view to_string(t_comin_error_code error_code) {
98 auto it = std::find_if(
99 error_strings.cbegin(), error_strings.cend(),
100 [error_code](const auto& a) { return std::get<0>(a) == error_code; });
101
102 if (error_strings.cend() != it) {
103 return std::get<1>(*it);
104 } else {
105 return "<unknown>"sv;
106 }
107}
108
109std::string_view category(t_comin_error_code error_code) {
110 if (COMIN_SUCCESS == error_code)
111 return "SUCCESS"sv;
112 else if (error_code < COMIN_WARNING)
113 return "INFO"sv;
114 else if (error_code < COMIN_ERROR_STATUS)
115 return "WARNING"sv;
116 else if (error_code < COMIN_ERROR_FATAL)
117 return "ERROR"sv;
118 else
119 return "FATAL ERROR"sv;
120}
121} // namespace comin::error
122
123extern "C" {
124
126 t_comin_error_code comin_error_get() {
127 return static_cast<t_comin_error_code>(comin_state_get_error_code());
128 }
129
132
135 const char* comin_error_get_string(t_comin_error_code error_code) {
136 return comin::error::to_string(error_code).data();
137 }
138
141 const char* comin_error_get_category(t_comin_error_code error_code) {
142 return comin::error::category(error_code).data();
143 }
144
148 void comin_plugin_finish(const char* routine, const char* text) {
149
150 if (comin_current_get_ep() == EP_FINISH)
151 return; // dont call finish again if we already in EP_FINISH
152
153 if (!comin::state.comin_host_errhandler_fct) {
154 // Fallback (best we could do before the errhandler is set)
155 comin::logging::message(12, routine, ": ", text);
156 int exit_no = 1;
157 MPI_Abort(MPI_COMM_WORLD, exit_no);
158 exit(exit_no);
159 } else {
160 comin::state.comin_host_errhandler_fct(routine, text);
161 }
162 }
163
164 /*
165 check the error code:
166 does nothing if error_code == COMIN_SUCCESS
167 prints the corresponding message
168 calls comin_plugin_finish if the error_code is an error or fatal error
169 */
171 int plugin_id = comin_current_get_plugin_id();
172 t_comin_error_code error_code = comin_error_get();
173 if (error_code == COMIN_SUCCESS)
174 return;
175
176 const char* category = comin_error_get_category(error_code);
177 const char* msg = comin_error_get_string(error_code);
178 if (error_code < COMIN_ERROR_STATUS) {
179 comin::logging::message(12, category, ": ", msg);
180 } else {
181 if (plugin_id > 0) {
182 comin_plugin_finish_f("ComIn", "%s: %s", category, msg);
183 } else {
185 category, msg);
186 }
187 }
188 }
189
190 /*
191 Set the internal error code to errcode. If the error handling mode is set to
192 automatic (default), calls comin_error_check to handle the error
193 immediately.
194 */
195 void comin_error_set(t_comin_error_code error_code) {
196 comin_state_set_error_code(error_code);
197 int plugin_id = comin_current_get_plugin_id();
198 if (plugin_id < 1 || !comin_current_get_plugin_errors_return())
200 }
201}
202
203namespace {
204constexpr bool check_all_error_codes_have_strings() {
205 for (size_t code = 0; code <= COMIN_ERROR_FATAL; ++code) {
206 bool found = false;
207 for (const auto& it : error_strings) {
208 if (std::get<0>(it) == code) {
209 found = true;
210 break;
211 }
212 }
213
214 if (!found) {
215 return false;
216 }
217 }
218
219 return true;
220}
221
222static_assert(check_all_error_codes_have_strings(),
223 "Not all error codes have error strings.");
224
225constexpr bool check_all_error_codes_have_one_string() {
226 for (size_t code = 0; code <= COMIN_ERROR_FATAL; ++code) {
227 unsigned nfound = 0;
228 for (const auto& it : error_strings) {
229 if (std::get<0>(it) == code) {
230 ++nfound;
231 }
232 }
233
234 if (nfound != 1) {
235 return false;
236 }
237 }
238
239 return true;
240}
241
242static_assert(check_all_error_codes_have_one_string(),
243 "Some error codes have multiple strings.");
244
245} // namespace
void comin_plugin_finish_f(const char *routine, const char *fmt,...)
const char * comin_error_get_category(t_comin_error_code error_code)
void comin_error_set(t_comin_error_code error_code)
t_comin_error_code comin_error_get()
Get the current ComIn error code.
const char * comin_error_get_string(t_comin_error_code error_code)
void comin_plugin_finish(const char *routine, const char *text)
void comin_error_reset()
Reset the current ComIn error code to COMIN_SUCCESS.
void comin_error_check()
const char * comin_current_get_plugin_name()
bool comin_current_get_plugin_errors_return()
int comin_state_get_error_code()
int comin_current_get_plugin_id()
t_comin_entry_point comin_current_get_ep()
void comin_state_set_error_code(int errcode)
t_comin_error_code
Definition comin.h:112
@ COMIN_ERROR_STATUS
Definition comin.h:116
@ COMIN_ERROR_VAR_METADATA_INCONSISTENT_TYPE
Definition comin.h:146
@ COMIN_ERROR_VAR_GET_CONTAINER_CAN_NOT_HALO_SYNCHRONIZED
Definition comin.h:143
@ COMIN_ERROR_SETUP_COMIN_ALREADY_INITIALIZED
Definition comin.h:126
@ COMIN_ERROR_FATAL
Definition comin.h:150
@ COMIN_ERROR_SETUP_ERRHANDLER_NOT_ASSOCIATED
Definition comin.h:127
@ COMIN_ERROR_CALLBACK_EP_ID_UNKNOWN
Definition comin.h:119
@ COMIN_ERROR_VAR_GET_VARIABLE_NOT_FOUND
Definition comin.h:142
@ COMIN_ERROR_VAR_GET_IRREGULAR_VAR_CAN_NOT_HALO_SYNCHRONIZED
Definition comin.h:144
@ COMIN_ERROR_VAR_REQUEST_EXISTS_IS_LMODEXCLUSIVE
Definition comin.h:131
@ COMIN_ERROR_POINTER_NOT_ASSOCIATED
Definition comin.h:136
@ COMIN_ERROR_VAR_REQUEST_EXISTS_REQUEST_LMODEXCLUSIVE
Definition comin.h:132
@ COMIN_ERROR_VAR_SYNC_HALO_NOT_ASSOCIATED
Definition comin.h:139
@ COMIN_ERROR_DESCRDATA_TIMESTEPLENGTH_NOT_SET
Definition comin.h:149
@ COMIN_ERROR_VAR_GET_VARIABLE_WRONG_TYPE
Definition comin.h:147
@ COMIN_ERROR_VAR_GET_NO_DEVICE
Definition comin.h:141
@ COMIN_ERROR_DESCRDATA_SET_FCT_GLB2LOC
Definition comin.h:120
@ COMIN_ERROR_VAR_REQUEST_AFTER_PRIMARYCONSTRUCTOR
Definition comin.h:130
@ COMIN_ERROR_METADATA_KEY_NOT_FOUND
Definition comin.h:123
@ COMIN_ERROR_VAR_ITEM_NOT_ASSOCIATED
Definition comin.h:134
@ COMIN_ERROR_INDEX_OUT_OF_BOUNDS
Definition comin.h:148
@ COMIN_ERROR_SETUP_ERRHANDLER_NOT_SET
Definition comin.h:128
@ COMIN_ERROR_FIELD_NOT_ALLOCATED
Definition comin.h:135
@ COMIN_INFO
Definition comin.h:114
@ COMIN_ERROR_METADATA_SET_OUTSIDE_PRIMARYCONSTRUCTOR
Definition comin.h:122
@ COMIN_SUCCESS
Definition comin.h:113
@ COMIN_ERROR_TRACER_REQUEST_NOT_FOR_ALL_DOMAINS
Definition comin.h:137
@ COMIN_WARNING
Definition comin.h:115
@ COMIN_ERROR_VAR_DESCRIPTOR_NOT_FOUND
Definition comin.h:133
@ COMIN_ERROR_VAR_SYNC_HALO_NOT_SUPPORTED_ZAXIS
Definition comin.h:145
@ COMIN_ERROR_VAR_SYNC_DEVICE_MEM_NOT_ASSOCIATED
Definition comin.h:138
@ COMIN_ERROR_SETUP_PRECISION_TEST_FAILED
Definition comin.h:129
@ COMIN_ERROR_CALLBACK_COMPLETE
Definition comin.h:118
@ COMIN_ERROR_METADATA_GET_INSIDE_PRIMARYCONSTRUCTOR
Definition comin.h:124
@ COMIN_ERROR_VAR_GET_OUTSIDE_SECONDARY_CONSTRUCTOR
Definition comin.h:140
@ COMIN_ERROR_CALLBACK_REGISTER_OUTSIDE_PRIMARYCONSTRUCTOR
Definition comin.h:117
@ COMIN_ERROR_SETUP_FINALIZE
Definition comin.h:125
@ COMIN_ERROR_DESCRDATA_FINALIZE
Definition comin.h:121
std::string_view to_string(t_comin_error_code error_code)
std::string_view category(t_comin_error_code error_code)