Sierra Toolkit  Version of the Day
ExceptionReport.cpp
1 
10 #include <vector>
11 #include <iostream>
12 #include <fstream>
13 #include <string>
14 
15 #include <mpi.h>
16 
17 #include <stk_util/diag/StringUtil.hpp>
18 #include <stk_util/diag/Trace.hpp>
19 #include <stk_util/parallel/ExceptionReport.hpp>
20 #include <stk_util/diag/Env.hpp>
21 
22 namespace sierra {
23 
24 
25 
26 // int get_next_message_id(int max_id_messages) {
27 // if(max_id_messages == -1) max_id_messages = get_default_max_message_id_displayed();
28 // return stk_classic::stk_get_next_message_id(max_id_messages);
29 // }
30 
31 namespace {
32 
33 std::ofstream *s_testErrorMessagesFile = NULL;
34 
35 bool s_dieOnFirstWarning = false;
36 bool s_dieOnFirstError = false;
37 
38 std::string s_testErrorMessagesPath;
39 
40 } // namespace <unnamed>
41 
42 void
43 test_error_messages_to_file_report_handler(const char * message, int type) {
44 
45  std::string new_message(message);
46  std::string::size_type start_pos;
47  //
48  // Strip out platform dependent exception related messages.
49  //
50  start_pos = new_message.find("exception thrown from");
51  if(start_pos != std::string::npos) {
52  int end_pos = new_message.find('\n');
53  new_message.erase(start_pos, (end_pos - start_pos) + 1);
54  }
55  start_pos = new_message.find("error thrown from");
56  if(start_pos != std::string::npos) {
57  int end_pos = new_message.find('\n');
58  new_message.erase(start_pos, (end_pos - start_pos) + 1);
59  }
60  start_pos = new_message.find("warning thrown from");
61  if(start_pos != std::string::npos) {
62  int end_pos = new_message.find('\n');
63  new_message.erase(start_pos, (end_pos - start_pos) + 1);
64  }
65  start_pos = new_message.find("Exception of type");
66  if(start_pos != std::string::npos) {
67  int end_pos = new_message.find('\n');
68  new_message.erase(start_pos, (end_pos - start_pos) + 1);
69  }
70  start_pos = new_message.find("with signature");
71  if(start_pos != std::string::npos) {
72  int end_pos = new_message.find('\n', start_pos);
73  new_message.erase(start_pos, (end_pos - start_pos) + 1);
74  }
75 
76  *s_testErrorMessagesFile << "********************************************************************************" << std::endl
77  << word_wrap(new_message.c_str(), 80, "** ")
78  << "********************************************************************************" << std::endl;
79  *s_testErrorMessagesFile << "===== ENDING ERROR FILE \"" << s_testErrorMessagesPath << "\" =====" << std::endl;
80 
81 
82 
83  int msgType = (type & stk_classic::MSG_TYPE_MASK);
84 
85 
86  bool dieNow = false;
87 
88  if((msgType == stk_classic::MSG_WARNING) && s_dieOnFirstWarning) {
89  dieNow = true;
90  }
91 
92  if((msgType == stk_classic::MSG_DOOMED) && s_dieOnFirstError) {
93  dieNow = true;
94  }
95 
96  if((msgType == stk_classic::MSG_EXCEPTION) && s_dieOnFirstError) {
97  dieNow = true;
98  }
99 
100  if(dieNow) {
101  delete s_testErrorMessagesFile;
102  MPI_Finalize();
103  std::exit(0);
104  }
105 
106 
107 
108 }
109 
110 
111 void
112 set_test_error_messages_file(
113  const std::string & test_error_messages_path)
114 {
115  s_testErrorMessagesPath = test_error_messages_path;
116 
117  s_testErrorMessagesFile = new std::ofstream(s_testErrorMessagesPath.c_str(), std::ios::out);
118  *s_testErrorMessagesFile << "===== STARTING ERROR FILE \"" << s_testErrorMessagesPath << "\" =====" << std::endl;
119 
120  stk_classic::set_report_handler(test_error_messages_to_file_report_handler);
121 }
122 
123 
124 std::ofstream *
125 get_test_error_messages_file()
126 {
127  return s_testErrorMessagesFile;
128 }
129 
130 
131  void set_test_error_messages_die_on_first_message(std::vector<ErrorDieEnum> errorTypes) {
132  for(unsigned int ierr=0; ierr< errorTypes.size(); ++ierr) {
133  if(errorTypes[ierr] == DIE_ON_WARN) {
134  s_dieOnFirstWarning = true;
135  }
136  if(errorTypes[ierr] == DIE_ON_ERROR) {
137  s_dieOnFirstError = true;
138  }
139  if(errorTypes[ierr] == DIE_ON_MESSAGE) {
140  s_dieOnFirstWarning = true;
141  s_dieOnFirstError = true;
142  }
143  }
144 
145 
146 }
147 
148 
149 bool get_test_error_messages_die_on_first_warning() {
150  return s_dieOnFirstWarning;
151 }
152 
153 bool get_test_error_messages_die_on_first_error() {
154  return s_dieOnFirstError;
155 }
156 
157 } // namespace sierra
158 
159 extern "C" {
160  void SIERRA_FORTRAN(report_error)(int &int_val, const char *message, const int message_length) {
161  switch (int_val) {
162  case 1:
163  sierra::Env::outputP0() << " " << std::string(message, message + message_length) << std::endl;
164  break;
165 
166  case 2:
167  sierra::RuntimeWarning() << "In Fmwk, " << std::string(message, message + message_length) << std::endl << WarnTrace;
168  break;
169 
170  case 3:
171  throw sierra::RuntimeError() << "In Fmwk, " << std::string(message, message + message_length) << std::endl << ErrorTrace;
172  }
173  }
174 }
Message is an exception.
Definition: Env.cpp:53
stk_classic::RuntimeWarningAdHoc RuntimeWarning
Deprecated.
std::ostream & outputP0()
Function outputP0 returns the processor output log stream on processor 0 and the null log stream on a...
Definition: Env.cpp:271
ExTemp1< std::runtime_error > RuntimeError
Defined in <stdexcept>
Definition: Exception.hpp:775
Message is a warning.
Message is a fatal error.
std::string word_wrap(const std::string &s, unsigned int line_length, const std::string &prefix, const std::string &prefix_first_line)
Function word_wrap reformats a string into multiple lines, none longer that line_length, the first line prefixed with prefix_first_line and the remaining lines prefixed with prefix.
Definition: StringUtil.cpp:249
REH set_report_handler(REH reh)
Function set_report_handler sets the exception report function to be called when an report_exception(...