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-2016 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  functionName,
131  sourceFileName,
132  sourceFileLineNumber,
133  ioStream
134  ) << msg << Foam::exit(FatalIOError);
135  }
136  else
137  {
138  std::cerr
139  << std::endl
140  << "--> FOAM FATAL IO ERROR:" << std::endl
141  << msg
142  << std::endl
143  << "file: " << ioStream.name()
144  << " at line " << ioStream.lineNumber() << '.'
145  << std::endl << std::endl
146  << " From function " << functionName
147  << std::endl
148  << " in file " << sourceFileName
149  << " at line " << sourceFileLineNumber << '.'
150  << std::endl;
151  ::exit(1);
152  }
153 }
154 
155 
156 Foam::IOerror::operator Foam::dictionary() const
157 {
158  dictionary errDict(error::operator dictionary());
159 
160  errDict.remove("type");
161  errDict.add("type", word("Foam::IOerror"));
162 
163  errDict.add("ioFileName", ioFileName());
164  errDict.add("ioStartLineNumber", ioStartLineNumber());
165  errDict.add("ioEndLineNumber", ioEndLineNumber());
166 
167  return errDict;
168 }
169 
170 
171 void Foam::IOerror::exit(const int)
172 {
174  {
175  jobInfo.add("FatalIOError", operator dictionary());
176  jobInfo.exit();
177  }
178 
179  if (abort_)
180  {
181  abort();
182  }
183 
184  if (Pstream::parRun())
185  {
186  Perr<< endl << *this << endl
187  << "\nFOAM parallel run exiting\n" << endl;
188  Pstream::exit(1);
189  }
190  else
191  {
192  if (throwExceptions_)
193  {
194  // Make a copy of the error to throw
195  IOerror errorException(*this);
196 
197  // Rewind the message buffer for the next error message
199 
200  throw errorException;
201  }
202  else
203  {
204  Perr<< endl << *this << endl
205  << "\nFOAM exiting\n" << endl;
206  ::exit(1);
207  }
208  }
209 }
210 
211 
213 {
215  {
216  jobInfo.add("FatalIOError", operator dictionary());
217  jobInfo.abort();
218  }
219 
220  if (abort_)
221  {
222  Perr<< endl << *this << endl
223  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
224  printStack(Perr);
225  ::abort();
226  }
227 
228  if (Pstream::parRun())
229  {
230  Perr<< endl << *this << endl
231  << "\nFOAM parallel run aborting\n" << endl;
232  printStack(Perr);
233  Pstream::abort();
234  }
235  else
236  {
237  if (throwExceptions_)
238  {
239  // Make a copy of the error to throw
240  IOerror errorException(*this);
241 
242  // Rewind the message buffer for the next error message
244 
245  throw errorException;
246  }
247  else
248  {
249  Perr<< endl << *this << endl
250  << "\nFOAM aborting\n" << endl;
251  printStack(Perr);
252  ::abort();
253  }
254  }
255 }
256 
257 
259 {
260  if (!os.bad())
261  {
262  os << endl
263  << ioErr.title().c_str() << endl
264  << ioErr.message().c_str() << endl << endl;
265 
266  os << "file: " << ioErr.ioFileName().c_str();
267 
268  if (ioErr.ioStartLineNumber() >= 0 && ioErr.ioEndLineNumber() >= 0)
269  {
270  os << " from line " << ioErr.ioStartLineNumber()
271  << " to line " << ioErr.ioEndLineNumber() << '.';
272  }
273  else if (ioErr.ioStartLineNumber() >= 0)
274  {
275  os << " at line " << ioErr.ioStartLineNumber() << '.';
276  }
277 
278  if (IOerror::level >= 2 && ioErr.sourceFileLineNumber())
279  {
280  os << endl << endl
281  << " From function " << ioErr.functionName().c_str() << endl
282  << " in file " << ioErr.sourceFileName().c_str()
283  << " at line " << ioErr.sourceFileLineNumber() << '.';
284  }
285  }
286 
287  return os;
288 }
289 
290 
291 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
292 // Global error definitions
293 
294 Foam::IOerror Foam::FatalIOError("--> FOAM FATAL IO ERROR: ");
295 
296 // ************************************************************************* //
static void printStack(Ostream &)
Helper function to print a stack.
virtual ~IOerror()
Destructor.
Definition: IOerror.C:54
Generic output stream.
Definition: OSstream.H:51
dictionary dict
IOerror(const string &title)
Construct from title string.
Definition: IOerror.C:36
bool remove(const word &)
Remove an entry specified by keyword.
Definition: dictionary.C:966
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
void abort()
Abort : used to stop code for fatal errors.
Definition: IOerror.C:212
bool bad() const
Return true if stream is corrupted.
Definition: IOstream.H:351
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
bool abort_
Definition: error.H:80
const string & title() const
Return the title of this error type.
label ioStartLineNumber() const
Definition: error.H:229
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
void rewind()
Rewind the OStringStream.
label lineNumber() const
Return current stream line number.
Definition: IOstream.H:438
label ioEndLineNumber() const
Definition: error.H:234
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:814
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:66
bool throwExceptions_
Definition: error.H:82
stressControl lookup("compactNormalStress") >> compactNormalStress
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
A class for handling words, derived from string.
Definition: word.H:59
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:297
string message() const
Definition: error.C:162
const string & functionName() const
Definition: error.H:107
label readLabel(Istream &is)
Definition: label.H:64
Report an I/O error.
Definition: error.H:196
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
static void exit(int errnum=1)
Exit program.
Definition: UPstream.C:46
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: IOerror.C:171
OSstream & operator()()
Explicitly convert to OSstream for << operations.
Definition: error.H:155
prefixOSstream Perr(cerr, "Perr")
Definition: IOstreams.H:54
const string & ioFileName() const
Definition: error.H:224
static void abort()
Abort program.
Definition: UPstream.C:52
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:394
An IOstream is an abstract base class for all input/output systems; be they streams, files, token lists etc.
Definition: IOstream.H:71
const string & sourceFileName() const
Definition: error.H:112
Ostream & operator<<(Ostream &, const ensightPart &)
OStringStream * messageStreamPtr_
Definition: error.H:83
JobInfo jobInfo
Definition: JobInfo.C:35
void abort()
Definition: JobInfo.C:169
static bool constructed
Definition: JobInfo.H:71
void exit()
Definition: JobInfo.C:163
IOerror FatalIOError
label sourceFileLineNumber() const
Definition: error.H:117