error.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "error.H"
27 #include "OStringStream.H"
28 #include "fileName.H"
29 #include "dictionary.H"
30 #include "jobInfo.H"
31 #include "Pstream.H"
32 #include "OSspecific.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 Foam::error::error(const string& title)
37 :
38  std::exception(),
39  messageStream(title, messageStream::FATAL),
40  functionName_("unknown"),
41  sourceFileName_("unknown"),
42  sourceFileLineNumber_(0),
43  abort_(env("FOAM_ABORT")),
44  throwExceptions_(false),
45  messageStreamPtr_(new OStringStream())
46 {
47  if (!messageStreamPtr_->good())
48  {
49  Perr<< endl
50  << "error::error(const string& title) : cannot open error stream"
51  << endl;
52  exit(1);
53  }
54 }
55 
56 
58 :
59  std::exception(),
60  messageStream(errDict),
61  functionName_(errDict.lookup("functionName")),
62  sourceFileName_(errDict.lookup("sourceFileName")),
63  sourceFileLineNumber_(errDict.lookup<label>("sourceFileLineNumber")),
64  abort_(env("FOAM_ABORT")),
65  throwExceptions_(false),
67 {
68  if (!messageStreamPtr_->good())
69  {
70  Perr<< endl
71  << "error::error(const dictionary& errDict) : "
72  "cannot open error stream"
73  << endl;
74  exit(1);
75  }
76 }
77 
78 
80 :
81  std::exception(),
82  messageStream(err),
86  abort_(err.abort_),
89 {
90  //*messageStreamPtr_ << err.message();
91 }
92 
93 
95 {
96  delete messageStreamPtr_;
97 }
98 
99 
100 Foam::OSstream& Foam::error::operator()
101 (
102  const char* functionName,
103  const char* sourceFileName,
104  const int sourceFileLineNumber
105 )
106 {
110 
111  return operator OSstream&();
112 }
113 
114 
115 Foam::OSstream& Foam::error::operator()
116 (
117  const string& functionName,
118  const char* sourceFileName,
119  const int sourceFileLineNumber
120 )
121 {
122  return operator()
123  (
124  functionName.c_str(),
127  );
128 }
129 
130 
131 Foam::error::operator Foam::OSstream&()
132 {
133  if (!messageStreamPtr_->good())
134  {
135  Perr<< endl
136  << "error::operator OSstream&() : error stream has failed"
137  << endl;
138  abort();
139  }
140 
141  return *messageStreamPtr_;
142 }
143 
144 
145 Foam::error::operator Foam::dictionary() const
146 {
147  dictionary errDict;
148 
149  string oneLineMessage(message());
150  oneLineMessage.replaceAll('\n', ' ');
151 
152  errDict.add("type", word("Foam::error"));
153  errDict.add("message", oneLineMessage);
154  errDict.add("function", functionName());
155  errDict.add("sourceFile", sourceFileName());
156  errDict.add("sourceFileLineNumber", sourceFileLineNumber());
157 
158  return errDict;
159 }
160 
161 
163 {
164  return messageStreamPtr_->str();
165 }
166 
167 
168 void Foam::error::exit(const int errNo)
169 {
171  {
172  jobInfo_.add("FatalError", operator dictionary());
173  jobInfo_.exit();
174  }
175 
176  if (abort_)
177  {
178  abort();
179  }
180 
181  if (Pstream::parRun())
182  {
183  Perr<< endl << *this << endl
184  << "\nFOAM parallel run exiting\n" << endl;
185  Pstream::exit(errNo);
186  }
187  else
188  {
189  if (throwExceptions_)
190  {
191  // Make a copy of the error to throw
192  error errorException(*this);
193 
194  // Rewind the message buffer for the next error message
196 
197  throw errorException;
198  }
199  else
200  {
201  Perr<< endl << *this << endl
202  << "\nFOAM exiting\n" << endl;
203  ::exit(errNo);
204  }
205  }
206 }
207 
208 
210 {
212  {
213  jobInfo_.add("FatalError", operator dictionary());
214  jobInfo_.abort();
215  }
216 
217  if (abort_)
218  {
219  Perr<< endl << *this << endl
220  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
221  printStack(Perr);
222  ::abort();
223  }
224 
225  if (Pstream::parRun())
226  {
227  Perr<< endl << *this << endl
228  << "\nFOAM parallel run aborting\n" << endl;
229  printStack(Perr);
230  Pstream::abort();
231  }
232  else
233  {
234  if (throwExceptions_)
235  {
236  // Make a copy of the error to throw
237  error errorException(*this);
238 
239  // Rewind the message buffer for the next error message
241 
242  throw errorException;
243  }
244  else
245  {
246  Perr<< endl << *this << endl
247  << "\nFOAM aborting\n" << endl;
248  printStack(Perr);
249  ::abort();
250  }
251  }
252 }
253 
254 
256 {
257  os << endl
258  << fErr.title().c_str() << endl
259  << fErr.message().c_str();
260 
261  if (error::level >= 2 && fErr.sourceFileLineNumber())
262  {
263  os << endl << endl
264  << " From function " << fErr.functionName().c_str() << endl
265  << " in file " << fErr.sourceFileName().c_str()
266  << " at line " << fErr.sourceFileLineNumber() << '.';
267  }
268 
269  return os;
270 }
271 
272 
273 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
274 // Global error definitions
275 
276 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");
277 
278 // ************************************************************************* //
static void printStack(Ostream &)
Helper function to print a stack.
Generic output stream.
Definition: OSstream.H:51
string & replaceAll(const string &oldStr, const string &newStr, size_type start=0)
Replace all occurrences of sub-string oldStr with newStr.
Definition: string.C:82
virtual ~error()
Destructor.
Definition: error.C:94
static bool constructed
Definition: jobInfo.H:72
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void exit()
Definition: jobInfo.C:198
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
bool abort_
Definition: error.H:80
const string & title() const
Return the title of this error type.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
void rewind()
Rewind the OStringStream.
string sourceFileName_
Definition: error.H:77
Class to handle messaging in a simple, consistent stream-based manner.
Definition: messageStream.H:68
jobInfo jobInfo_
Definition: jobInfo.C:44
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:330
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: error.C:168
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:1133
error(const string &title)
Construct from title string.
Definition: error.C:36
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:66
label sourceFileLineNumber_
Definition: error.H:78
bool throwExceptions_
Definition: error.H:82
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
stressControl lookup("compactNormalStress") >> compactNormalStress
A class for handling words, derived from string.
Definition: word.H:59
string message() const
Definition: error.C:162
void abort()
Abort : used to stop code for fatal errors.
Definition: error.C:209
const string & functionName() const
Definition: error.H:107
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:54
static void exit(int errnum=1)
Exit program.
Definition: UPstream.C:46
prefixOSstream Perr(cerr, "Perr")
Definition: IOstreams.H:54
string functionName_
Definition: error.H:76
static void abort()
Abort program.
Definition: UPstream.C:52
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
const string & sourceFileName() const
Definition: error.H:112
Ostream & operator<<(Ostream &, const ensightPart &)
string str() const
Return the string.
OStringStream * messageStreamPtr_
Definition: error.H:83
bool env(const word &)
Return true if environment variable of given name is defined.
Definition: POSIX.C:91
A class for handling character strings derived from std::string.
Definition: string.H:76
Output to memory buffer stream.
Definition: OStringStream.H:49
void abort()
Definition: jobInfo.C:204
label sourceFileLineNumber() const
Definition: error.H:117