IOerror.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "error.H"
30 #include "StringStream.H"
31 #include "fileName.H"
32 #include "dictionary.H"
33 #include "JobInfo.H"
34 #include "Pstream.H"
35 
36 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
37 
38 Foam::IOerror::IOerror(const string& title)
39 :
40  error(title),
41  ioFileName_("unknown"),
42  ioStartLineNumber_(-1),
43  ioEndLineNumber_(-1)
44 {}
45 
46 
48 :
49  error(errDict),
50  ioFileName_(errDict.get<string>("ioFileName")),
51  ioStartLineNumber_(errDict.get<label>("ioStartLineNumber")),
52  ioEndLineNumber_(errDict.get<label>("ioEndLineNumber"))
53 {}
54 
55 
56 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
57 
59 {}
60 
61 
62 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
63 
64 Foam::OSstream& Foam::IOerror::operator()
65 (
66  const char* functionName,
67  const char* sourceFileName,
68  const int sourceFileLineNumber,
69  const string& ioFileName,
70  const label ioStartLineNumber,
71  const label ioEndLineNumber
72 )
73 {
74  error::operator()(functionName, sourceFileName, sourceFileLineNumber);
75  ioFileName_ = ioFileName;
76  ioStartLineNumber_ = ioStartLineNumber;
77  ioEndLineNumber_ = ioEndLineNumber;
78 
79  return operator OSstream&();
80 }
81 
82 
83 Foam::OSstream& Foam::IOerror::operator()
84 (
85  const char* functionName,
86  const char* sourceFileName,
87  const int sourceFileLineNumber,
88  const IOstream& ioStream
89 )
90 {
91  return operator()
92  (
93  functionName,
94  sourceFileName,
95  sourceFileLineNumber,
96  ioStream.name(),
97  ioStream.lineNumber(),
98  -1
99  );
100 }
101 
102 
103 Foam::OSstream& Foam::IOerror::operator()
104 (
105  const char* functionName,
106  const char* sourceFileName,
107  const int sourceFileLineNumber,
108  const dictionary& dict
109 )
110 {
111  return operator()
112  (
113  functionName,
114  sourceFileName,
115  sourceFileLineNumber,
116  dict.name(),
119  );
120 }
121 
122 
124 (
125  const char* functionName,
126  const char* sourceFileName,
127  const int sourceFileLineNumber,
128  const IOstream& ioStream,
129  const string& msg
130 )
131 {
133  {
135  (
136  functionName,
137  sourceFileName,
138  sourceFileLineNumber,
139  ioStream
140  ) << msg << Foam::exit(FatalIOError);
141  }
142  else
143  {
144  std::cerr
145  << nl
146  << "--> FOAM FATAL IO ERROR:" << nl
147  << msg << nl
148  << "file: " << ioStream.name()
149  << " at line " << ioStream.lineNumber() << '.' << nl << nl
150  << " From " << functionName << nl
151  << " in file " << sourceFileName
152  << " at line " << sourceFileLineNumber << '.' << std::endl;
153  std::exit(1);
154  }
155 }
156 
157 
158 Foam::IOerror::operator Foam::dictionary() const
159 {
160  dictionary errDict(error::operator dictionary());
161 
162  errDict.remove("type");
163  errDict.add("type", word("Foam::IOerror"));
164 
165  errDict.add("ioFileName", ioFileName());
166  errDict.add("ioStartLineNumber", ioStartLineNumber());
167  errDict.add("ioEndLineNumber", ioEndLineNumber());
168 
169  return errDict;
170 }
171 
172 
173 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
174 
175 void Foam::IOerror::exitOrAbort(const int errNo, const bool isAbort)
176 {
177  if (!throwing_ && JobInfo::constructed)
178  {
179  jobInfo.add("FatalIOError", operator dictionary());
180  if (isAbort || error::useAbort())
181  {
182  jobInfo.abort();
183  }
184  else
185  {
186  jobInfo.exit();
187  }
188  }
189 
190  if (throwing_ && !isAbort)
191  {
192  // Make a copy of the error to throw
193  IOerror errorException(*this);
194 
195  // Reset the message buffer for the next error message
196  messageStreamPtr_->reset();
197 
198  throw errorException;
199  }
200  else if (error::useAbort())
201  {
202  Perr<< nl << *this << nl
203  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
205  std::abort();
206  }
207  else if (Pstream::parRun())
208  {
209  if (isAbort)
210  {
211  Perr<< nl << *this << nl
212  << "\nFOAM parallel run aborting\n" << endl;
214  Pstream::abort();
215  }
216  else
217  {
218  Perr<< nl << *this << nl
219  << "\nFOAM parallel run exiting\n" << endl;
220  Pstream::exit(errNo);
221  }
222  }
223  else
224  {
225  if (isAbort)
226  {
227  Perr<< nl << *this << nl
228  << "\nFOAM aborting\n" << endl;
230 
231  #ifdef _WIN32
232  std::exit(1); // Prefer exit() to avoid unnecessary warnings
233  #else
234  std::abort();
235  #endif
236  }
237  else
238  {
239  Perr<< nl << *this << nl
240  << "\nFOAM exiting\n" << endl;
241  std::exit(errNo);
242  }
243  }
244 }
245 
246 
247 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
248 
249 void Foam::IOerror::exit(const int)
250 {
251  exitOrAbort(1, false);
252 }
253 
254 
256 {
257  exitOrAbort(1, true);
258 }
259 
260 
261 void Foam::IOerror::write(Ostream& os, const bool includeTitle) const
262 {
263  if (os.bad())
264  {
265  return;
266  }
267 
268  os << nl;
269  if (includeTitle && !title().empty())
270  {
271  os << title().c_str()
272  << "(openfoam-" << foamVersion::api;
273 
274  if (foamVersion::patched())
275  {
276  // Patch-level, when defined
277  os << " patch=" << foamVersion::patch.c_str();
278  }
279  os << ')' << nl;
280  }
281  os << message().c_str();
282 
283 
284  if (!ioFileName().empty())
285  {
286  os << nl << nl
287  << "file: " << ioFileName().c_str();
288 
289  if (ioStartLineNumber() >= 0)
290  {
291  os << " at line " << ioStartLineNumber();
292  if (ioStartLineNumber() < ioEndLineNumber())
293  {
294  os << " to " << ioEndLineNumber();
295  }
296  os << '.';
297  }
298  }
299 
300 
301  const label lineNo = sourceFileLineNumber();
302 
303  if (IOerror::level >= 2 && lineNo && !functionName().empty())
304  {
305  os << nl << nl
306  << " From " << functionName().c_str() << nl;
307 
308  if (!sourceFileName().empty())
309  {
310  os << " in file " << sourceFileName().c_str();
311 
312  if (lineNo > 0)
313  {
314  os << " at line " << lineNo << '.';
315  }
316  }
317  }
318 }
319 
320 
321 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
322 
324 {
325  err.write(os);
326 
327  return os;
328 }
329 
330 
331 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
332 // Global error definitions
333 
334 Foam::IOerror Foam::FatalIOError("--> FOAM FATAL IO ERROR: ");
335 
336 
337 // ************************************************************************* //
Foam::JobInfo::exit
void exit()
End with "termination=exit".
Definition: JobInfo.C:172
Foam::error::printStack
static void printStack(Ostream &os)
Helper function to print a stack.
Definition: dummyPrintStack.C:36
Foam::IOerror::abort
void abort()
Abort : used to stop code for fatal errors.
Definition: IOerror.C:255
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::foamVersion::patched
bool patched()
Foam::IOerror::IOerror
IOerror(const string &title)
Construct from title string.
Definition: IOerror.C:38
Foam::UPstream::parRun
static bool & parRun()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
Foam::messageStream::level
static int level
The output level (verbosity) of messages.
Definition: messageStream.H:107
Foam::IOstream
An IOstream is an abstract base class for all input/output systems; be they streams,...
Definition: IOstream.H:75
StringStream.H
Input/output from string buffers.
Foam::FatalIOError
IOerror FatalIOError
Foam::UPstream::abort
static void abort()
Call MPI_Abort with no other checks or cleanup.
Definition: UPstream.C:70
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::string
A class for handling character strings derived from std::string.
Definition: string.H:73
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::IOerror::SafeFatalIOError
static void SafeFatalIOError(const char *functionName, const char *sourceFileName, const int sourceFileLineNumber, const IOstream &ioStream, const string &msg)
Print basic message and exit.
Definition: IOerror.C:124
Foam::dictionary::name
const fileName & name() const
The dictionary name.
Definition: dictionary.H:446
Foam::foamVersion::api
const int api
error.H
Foam::dictionary::startLineNumber
label startLineNumber() const
Return line number of first token in dictionary.
Definition: dictionary.C:205
Foam::dictionary::endLineNumber
label endLineNumber() const
Return line number of last token in dictionary.
Definition: dictionary.C:216
fileName.H
Foam::IOstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.C:39
Foam::OSstream
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:54
Foam::IOerror::~IOerror
virtual ~IOerror() noexcept
Destructor.
Definition: IOerror.C:58
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::IOstream::bad
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:242
Pstream.H
Foam::error::useAbort
static bool useAbort()
True if FOAM_ABORT is on.
Definition: error.C:74
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::error::operator()
OSstream & operator()()
Explicit convert to OSstream for << operations.
Definition: error.H:198
Foam::jobInfo
JobInfo jobInfo
Definition: JobInfo.C:49
Foam::Perr
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
Foam::IOerror::exit
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: IOerror.C:249
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::JobInfo::constructed
static bool constructed
Global value for constructed job info.
Definition: JobInfo.H:80
Foam::IOerror::write
void write(Ostream &os, const bool includeTitle=true) const
Print error message.
Definition: IOerror.C:261
dictionary.H
JobInfo.H
Foam::IOstream::lineNumber
label lineNumber() const
Const access to the current stream line number.
Definition: IOstream.H:309
Foam::IOerror
Report an I/O error.
Definition: error.H:238
Foam::dictionary::add
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:708
Foam::JobInfo::abort
void abort()
End with "termination=abort".
Definition: JobInfo.C:178
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::error
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:70
Foam::UPstream::exit
static void exit(int errNo=1)
Shutdown (finalize) MPI as required and exit program with errNo.
Definition: UPstream.C:63