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