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 | Copyright (C) 2011 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 "JobInfo.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 Foam::IOerror::IOerror(const string& title)
37 :
38  error(title),
39  ioFileName_("unknown"),
40  ioStartLineNumber_(-1),
41  ioEndLineNumber_(-1)
42 {}
43 
44 
46 :
47  error(errDict),
48  ioFileName_(errDict.lookup("ioFileName")),
49  ioStartLineNumber_(readLabel(errDict.lookup("ioStartLineNumber"))),
50  ioEndLineNumber_(readLabel(errDict.lookup("ioEndLineNumber")))
51 {}
52 
53 
55 {}
56 
57 
58 Foam::OSstream& Foam::IOerror::operator()
59 (
60  const char* functionName,
61  const char* sourceFileName,
62  const int sourceFileLineNumber,
63  const string& ioFileName,
66 )
67 {
69  ioFileName_ = ioFileName;
70  ioStartLineNumber_ = ioStartLineNumber;
71  ioEndLineNumber_ = ioEndLineNumber;
72 
73  return operator OSstream&();
74 }
75 
76 
77 Foam::OSstream& Foam::IOerror::operator()
78 (
79  const char* functionName,
80  const char* sourceFileName,
81  const int sourceFileLineNumber,
82  const IOstream& ioStream
83 )
84 {
85  return operator()
86  (
90  ioStream.name(),
91  ioStream.lineNumber(),
92  -1
93  );
94 }
95 
96 
97 Foam::OSstream& Foam::IOerror::operator()
98 (
99  const char* functionName,
100  const char* sourceFileName,
101  const int sourceFileLineNumber,
102  const dictionary& dict
103 )
104 {
105  return operator()
106  (
107  functionName,
110  dict.name(),
111  dict.startLineNumber(),
112  dict.endLineNumber()
113  );
114 }
115 
116 
118 (
119  const char* functionName,
120  const char* sourceFileName,
121  const int sourceFileLineNumber,
122  const IOstream& ioStream,
123  const string& msg
124 )
125 {
127  {
129  (
130  "primitiveEntry::readEntry(const dictionary&, Istream&)",
131  ioStream
132  ) << msg << Foam::exit(FatalIOError);
133  }
134  else
135  {
136  std::cerr
137  << std::endl
138  << "--> FOAM FATAL IO ERROR:" << std::endl
139  << msg
140  << std::endl
141  << "file: " << ioStream.name()
142  << " at line " << ioStream.lineNumber() << '.'
143  << std::endl << std::endl
144  << " From function " << functionName
145  << std::endl
146  << " in file " << sourceFileName
147  << " at line " << sourceFileLineNumber << '.'
148  << std::endl;
149  ::exit(1);
150  }
151 }
152 
153 
154 Foam::IOerror::operator Foam::dictionary() const
155 {
156  dictionary errDict(error::operator dictionary());
157 
158  errDict.remove("type");
159  errDict.add("type", word("Foam::IOerror"));
160 
161  errDict.add("ioFileName", ioFileName());
162  errDict.add("ioStartLineNumber", ioStartLineNumber());
163  errDict.add("ioEndLineNumber", ioEndLineNumber());
164 
165  return errDict;
166 }
167 
168 
169 void Foam::IOerror::exit(const int)
170 {
172  {
173  jobInfo.add("FatalIOError", operator dictionary());
174  jobInfo.exit();
175  }
176 
177  if (abort_)
178  {
179  abort();
180  }
181 
182  if (Pstream::parRun())
183  {
184  Perr<< endl << *this << endl
185  << "\nFOAM parallel run exiting\n" << endl;
186  Pstream::exit(1);
187  }
188  else
189  {
190  if (throwExceptions_)
191  {
192  // Make a copy of the error to throw
193  IOerror errorException(*this);
194 
195  // Rewind the message buffer for the next error message
197 
198  throw errorException;
199  }
200  else
201  {
202  Perr<< endl << *this << endl
203  << "\nFOAM exiting\n" << endl;
204  ::exit(1);
205  }
206  }
207 }
208 
209 
211 {
213  {
214  jobInfo.add("FatalIOError", operator dictionary());
215  jobInfo.abort();
216  }
217 
218  if (abort_)
219  {
220  Perr<< endl << *this << endl
221  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
222  printStack(Perr);
223  ::abort();
224  }
225 
226  if (Pstream::parRun())
227  {
228  Perr<< endl << *this << endl
229  << "\nFOAM parallel run aborting\n" << endl;
230  printStack(Perr);
231  Pstream::abort();
232  }
233  else
234  {
235  if (throwExceptions_)
236  {
237  // Make a copy of the error to throw
238  IOerror errorException(*this);
239 
240  // Rewind the message buffer for the next error message
242 
243  throw errorException;
244  }
245  else
246  {
247  Perr<< endl << *this << endl
248  << "\nFOAM aborting\n" << endl;
249  printStack(Perr);
250  ::abort();
251  }
252  }
253 }
254 
255 
257 {
258  if (!os.bad())
259  {
260  os << endl
261  << ioErr.title().c_str() << endl
262  << ioErr.message().c_str() << endl << endl;
263 
264  os << "file: " << ioErr.ioFileName().c_str();
265 
266  if (ioErr.ioStartLineNumber() >= 0 && ioErr.ioEndLineNumber() >= 0)
267  {
268  os << " from line " << ioErr.ioStartLineNumber()
269  << " to line " << ioErr.ioEndLineNumber() << '.';
270  }
271  else if (ioErr.ioStartLineNumber() >= 0)
272  {
273  os << " at line " << ioErr.ioStartLineNumber() << '.';
274  }
275 
276  if (IOerror::level >= 2 && ioErr.sourceFileLineNumber())
277  {
278  os << endl << endl
279  << " From function " << ioErr.functionName().c_str() << endl
280  << " in file " << ioErr.sourceFileName().c_str()
281  << " at line " << ioErr.sourceFileLineNumber() << '.';
282  }
283  }
284 
285  return os;
286 }
287 
288 
289 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
290 // Global error definitions
291 
292 Foam::IOerror Foam::FatalIOError("--> FOAM FATAL IO ERROR: ");
293 
294 // ************************************************************************* //
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:380
bool abort_
Definition: error.H:80
label ioStartLineNumber() const
Definition: error.H:229
label sourceFileLineNumber() const
Definition: error.H:117
Generic output stream.
Definition: OSstream.H:51
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:351
bool throwExceptions_
Definition: error.H:82
virtual ~IOerror()
Destructor.
Definition: IOerror.C:54
bool remove(const word &)
Remove an entry specified by keyword.
Definition: dictionary.C:891
A class for handling words, derived from string.
Definition: word.H:59
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const string & sourceFileName() const
Definition: error.H:112
prefixOSstream Perr(cerr,"Perr")
Definition: IOstreams.H:54
static void abort()
Abort program.
Definition: UPstream.C:52
static void printStack(Ostream &)
Helper function to print a stack.
Report an I/O error.
Definition: error.H:196
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
Ostream & operator<<(Ostream &, const edgeMesh &)
Definition: edgeMeshIO.C:133
label readLabel(Istream &is)
Definition: label.H:64
void abort()
Abort : used to stop code for fatal errors.
Definition: IOerror.C:210
OStringStream * messageStreamPtr_
Definition: error.H:83
static void exit(int errnum=1)
Exit program.
Definition: UPstream.C:46
dictionary dict
label ioEndLineNumber() const
Definition: error.H:234
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
stressControl lookup("compactNormalStress") >> compactNormalStress
IOerror FatalIOError
static void SafeFatalIOError(const char *functionName, const char *sourceFileName, const int sourceFileLineNumber, const IOstream &, const string &msg)
Print basic message and exit. Uses cerr if streams not constructed.
Definition: IOerror.C:118
const string & title() const
Return the title of this error type.
IOerror(const string &title)
Construct from title string.
Definition: IOerror.C:36
void rewind()
Rewind the OStringStream.
const string & ioFileName() const
Definition: error.H:224
label lineNumber() const
Return current stream line number.
Definition: IOstream.H:438
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:739
static bool constructed
Definition: JobInfo.H:71
string message() const
Definition: error.C:162
OSstream & operator()()
Explicitly convert to OSstream for << operations.
Definition: error.H:155
void abort()
Definition: JobInfo.C:170
JobInfo jobInfo
Definition: JobInfo.C:35
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:66
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
const string & functionName() const
Definition: error.H:107
#define FatalIOErrorIn(functionName, ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:325
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: IOerror.C:169
void exit()
Definition: JobInfo.C:164
An IOstream is an abstract base class for all input/output systems; be they streams, files, token lists etc.
Definition: IOstream.H:71