Skip to content

Commit 6767b3b

Browse files
committed
create error handling logic
1 parent d50b976 commit 6767b3b

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

src/pcms/assert.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,50 @@
44
#include <cstdlib>
55
namespace pcms
66
{
7+
8+
namespace
9+
{
10+
error_mode current_mode = error_mode::throw_exception;
11+
}
12+
13+
void set_error_mode(error_mode mode)
14+
{
15+
current_mode = mode;
16+
}
17+
18+
void handle_error(const exception& e)
19+
{
20+
switch (current_mode) {
21+
case error_mode::throw_exception: throw e;
22+
23+
case error_mode::abort: std::abort();
24+
25+
case error_mode::return_code:
26+
default: break;
27+
}
28+
}
29+
30+
void handle_mpi_error(const pcms::exception& e)
31+
{
32+
int local_fatal = (e.level() == pcms::error_level::fatal);
33+
int global_fatal = 0;
34+
35+
MPI_Allreduce(&local_fatal, &global_fatal, 1, MPI_INT, MPI_MAX,
36+
MPI_COMM_WORLD);
37+
38+
switch (current_mode) {
39+
case pcms::error_mode::throw_exception: throw e;
40+
41+
case pcms::error_mode::abort:
42+
if (global_fatal)
43+
MPI_Abort(MPI_COMM_WORLD, e.code());
44+
break;
45+
46+
case pcms::error_mode::return_code:
47+
default: break;
48+
}
49+
}
50+
751
void Pcms_Assert_Fail(const char* msg)
852
{
953
printError("%s", msg);

src/pcms/assert.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#ifndef PCMS_COUPLING_ASSERT_H
22
#define PCMS_COUPLING_ASSERT_H
33
#include <cassert>
4+
#include <exception>
5+
#include <string>
6+
#include <sstream>
47
#include <mpi.h>
58

69
// https://stackoverflow.com/questions/16683146/can-macros-be-overloaded-by-number-of-arguments
@@ -44,6 +47,51 @@
4447

4548
namespace pcms
4649
{
50+
enum class error_level
51+
{
52+
recoverable, // safe to continue
53+
resource_leak, // may cause resource leaks
54+
fatal // undefined or broken state
55+
};
56+
57+
enum class error_mode
58+
{
59+
return_code,
60+
throw_exception,
61+
abort
62+
};
63+
64+
class exception : public std::exception
65+
{
66+
public:
67+
exception(std::string message, int error_code = 0,
68+
error_level level = error_level::fatal, std::string specific = {})
69+
: error_code_(error_code), level_(level)
70+
{
71+
std::ostringstream oss;
72+
oss << message;
73+
if (!specific.empty())
74+
oss << " | Details: " << specific;
75+
if (error_code_ != 0)
76+
oss << " | Error code: " << error_code_;
77+
error_message_ = oss.str();
78+
}
79+
80+
const char* what() const noexcept override { return error_message_.c_str(); }
81+
82+
int code() const noexcept { return error_code_; }
83+
error_level level() const noexcept { return level_; }
84+
85+
private:
86+
std::string error_message_;
87+
int error_code_;
88+
error_level level_;
89+
};
90+
91+
void set_error_mode(error_mode mode);
92+
void handle_error(const exception& e);
93+
void handle_mpi_error(const exception& e);
94+
4795
// from scorec/core/pcu_fail.h
4896
void Pcms_Assert_Fail(const char* msg) __attribute__((noreturn));
4997
} // namespace pcms

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ if(Catch2_FOUND)
382382
list(
383383
APPEND
384384
PCMS_UNIT_TEST_SOURCES
385+
test_error_handling.cpp
385386
test_field_transfer.cpp
386387
test_uniform_grid.cpp
387388
test_omega_h_copy.cpp

test/test_error_handling.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <catch2/catch_test_macros.hpp>
2+
#include "pcms/assert.h"
3+
#include "pcms/print.h"
4+
#include <iostream>
5+
6+
int raise_error(int code)
7+
{
8+
if (code) {
9+
pcms::handle_error(pcms::exception("Mesh validation failed", 1,
10+
pcms::error_level::recoverable));
11+
12+
return 1;
13+
}
14+
return 0;
15+
}
16+
17+
TEST_CASE("pcms error handling test")
18+
{
19+
REQUIRE_THROWS_AS(raise_error(1), pcms::exception);
20+
}

0 commit comments

Comments
 (0)