error.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-2014 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
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  throwExceptions_(false),
44  messageStreamPtr_(new OStringStream())
45 {
46  if (!messageStreamPtr_->good())
47  {
48  Perr<< endl
49  << "error::error(const string& title) : cannot open error stream"
50  << endl;
51  exit(1);
52  }
53 }
54 
55 
57 :
58  std::exception(),
59  messageStream(errDict),
60  functionName_(errDict.lookup("functionName")),
61  sourceFileName_(errDict.lookup("sourceFileName")),
62  sourceFileLineNumber_(readLabel(errDict.lookup("sourceFileLineNumber"))),
63  throwExceptions_(false),
64  messageStreamPtr_(new OStringStream())
65 {
66  if (!messageStreamPtr_->good())
67  {
68  Perr<< endl
69  << "error::error(const dictionary& errDict) : "
70  "cannot open error stream"
71  << endl;
72  exit(1);
73  }
74 }
75 
76 
78 :
79  std::exception(),
80  messageStream(err),
81  functionName_(err.functionName_),
82  sourceFileName_(err.sourceFileName_),
83  sourceFileLineNumber_(err.sourceFileLineNumber_),
84  throwExceptions_(err.throwExceptions_),
85  messageStreamPtr_(new OStringStream(*err.messageStreamPtr_))
86 {
87  //*messageStreamPtr_ << err.message();
88 }
89 
90 
92 {
93  delete messageStreamPtr_;
94 }
95 
96 
97 Foam::OSstream& Foam::error::operator()
98 (
99  const char* functionName,
100  const char* sourceFileName,
101  const int sourceFileLineNumber
102 )
103 {
104  functionName_ = functionName;
105  sourceFileName_ = sourceFileName;
106  sourceFileLineNumber_ = sourceFileLineNumber;
107 
108  return operator OSstream&();
109 }
110 
111 
112 Foam::OSstream& Foam::error::operator()
113 (
114  const string& functionName,
115  const char* sourceFileName,
116  const int sourceFileLineNumber
117 )
118 {
119  return operator()
120  (
121  functionName.c_str(),
122  sourceFileName,
123  sourceFileLineNumber
124  );
125 }
126 
127 
128 Foam::error::operator Foam::OSstream&()
129 {
130  if (!messageStreamPtr_->good())
131  {
132  Perr<< endl
133  << "error::operator OSstream&() : error stream has failed"
134  << endl;
135  abort();
136  }
137 
138  return *messageStreamPtr_;
139 }
140 
141 
142 Foam::error::operator Foam::dictionary() const
143 {
144  dictionary errDict;
145 
146  string oneLineMessage(message());
147  oneLineMessage.replaceAll('\n', ' ');
148 
149  errDict.add("type", word("Foam::error"));
150  errDict.add("message", oneLineMessage);
151  errDict.add("function", functionName());
152  errDict.add("sourceFile", sourceFileName());
153  errDict.add("sourceFileLineNumber", sourceFileLineNumber());
154 
155  return errDict;
156 }
157 
158 
160 {
161  return messageStreamPtr_->str();
162 }
163 
164 
165 void Foam::error::exit(const int errNo)
166 {
167  if (!throwExceptions_ && JobInfo::constructed)
168  {
169  jobInfo.add("FatalError", operator dictionary());
170  jobInfo.exit();
171  }
172 
173  if (env("FOAM_ABORT"))
174  {
175  abort();
176  }
177 
178  if (Pstream::parRun())
179  {
180  Perr<< endl << *this << endl
181  << "\nFOAM parallel run exiting\n" << endl;
182  Pstream::exit(errNo);
183  }
184  else
185  {
186  if (throwExceptions_)
187  {
188  // Make a copy of the error to throw
189  error errorException(*this);
190 
191  // Rewind the message buffer for the next error message
192  messageStreamPtr_->rewind();
193 
194  throw errorException;
195  }
196  else
197  {
198  Perr<< endl << *this << endl
199  << "\nFOAM exiting\n" << endl;
200  ::exit(1);
201  }
202  }
203 }
204 
205 
207 {
208  if (!throwExceptions_ && JobInfo::constructed)
209  {
210  jobInfo.add("FatalError", operator dictionary());
211  jobInfo.abort();
212  }
213 
214  if (env("FOAM_ABORT"))
215  {
216  Perr<< endl << *this << endl
217  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
218  printStack(Perr);
219  ::abort();
220  }
221 
222  if (Pstream::parRun())
223  {
224  Perr<< endl << *this << endl
225  << "\nFOAM parallel run aborting\n" << endl;
226  printStack(Perr);
227  Pstream::abort();
228  }
229  else
230  {
231  if (throwExceptions_)
232  {
233  // Make a copy of the error to throw
234  error errorException(*this);
235 
236  // Rewind the message buffer for the next error message
237  messageStreamPtr_->rewind();
238 
239  throw errorException;
240  }
241  else
242  {
243  Perr<< endl << *this << endl
244  << "\nFOAM aborting\n" << endl;
245  printStack(Perr);
246  // Prefer ::exit(1) to avoid unnecessary warnings on Windows
247 #ifdef MSWIN
248  ::exit(1);
249 #else
250  ::abort();
251 #endif
252  }
253  }
254 }
255 
256 
258 {
259  os << endl
260  << fErr.title().c_str() << endl
261  << fErr.message().c_str();
262 
263  if (error::level >= 2 && fErr.sourceFileLineNumber())
264  {
265  os << endl << endl
266  << " From function " << fErr.functionName().c_str() << endl
267  << " in file " << fErr.sourceFileName().c_str()
268  << " at line " << fErr.sourceFileLineNumber() << '.';
269  }
270 
271  return os;
272 }
273 
274 
275 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
276 // Global error definitions
277 
278 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");
279 
280 // ************************************************************************* //
Foam::JobInfo::exit
void exit()
Definition: JobInfo.C:164
Foam::error::sourceFileName
const string & sourceFileName() const
Definition: error.H:111
Foam::env
bool env(const word &)
Return true if environment variable of given name is defined.
Definition: POSIX.C:95
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::messageStream
Class to handle messaging in a simple, consistent stream-based manner.
Definition: messageStream.H:68
Foam::UPstream::exit
static void exit(int errnum=1)
Exit program.
Definition: UPstream.C:46
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::Perr
prefixOSstream Perr(cerr, "Perr")
Definition: IOstreams.H:54
Foam::messageStream::level
static int level
Definition: messageStream.H:97
Foam::error::functionName
const string & functionName() const
Definition: error.H:106
Foam::UPstream::abort
static void abort()
Abort program.
Definition: UPstream.C:52
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::string
A class for handling character strings derived from std::string.
Definition: string.H:74
Foam::error::error
error(const string &title)
Construct from title string.
Definition: error.C:36
error.H
OStringStream.H
fileName.H
Foam::OSstream
Generic output stream.
Definition: OSstream.H:51
Foam::operator<<
Ostream & operator<<(Ostream &, const edgeMesh &)
Definition: edgeMeshIO.C:130
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Pstream.H
Foam::error::message
string message() const
Definition: error.C:159
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::error::exit
void exit(const int errNo=1)
Exit : can be called for any error to exit program.
Definition: error.C:165
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::jobInfo
JobInfo jobInfo
Definition: JobInfo.C:35
Foam::error::sourceFileLineNumber
label sourceFileLineNumber() const
Definition: error.H:116
Foam::error::~error
virtual ~error()
Destructor.
Definition: error.C:91
Foam::JobInfo::constructed
static bool constructed
Definition: JobInfo.H:71
Foam::error::abort
void abort()
Abort : used to stop code for fatal errors.
Definition: error.C:206
Foam::OStringStream
Output to memory buffer stream.
Definition: OStringStream.H:49
Foam::error::messageStreamPtr_
OStringStream * messageStreamPtr_
Definition: error.H:81
dictionary.H
Foam::readLabel
label readLabel(Istream &is)
Definition: label.H:64
Foam::messageStream::title
const string & title() const
Return the title of this error type.
Definition: messageStream.H:118
JobInfo.H
Foam::JobInfo::abort
void abort()
Definition: JobInfo.C:170
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:53
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
Foam::error
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:66
Foam::dictionary::add
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:729
lookup
stressControl lookup("compactNormalStress") >> compactNormalStress