FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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 <OpenFOAM/OStringStream.H>
28 #include <OpenFOAM/fileName.H>
29 #include <OpenFOAM/dictionary.H>
30 #include <OpenFOAM/JobInfo.H>
31 #include <OpenFOAM/Pstream.H>
32 #include <OpenFOAM/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  abort_(env("FOAM_ABORT")),
44  throwExceptions_(false),
45  messageStreamPtr_(new OStringStream())
46 {
47  if (!messageStreamPtr_->good())
48  {
49  Perr<< endl
50  << "error::error(const string& title) : cannot open error stream"
51  << endl;
52  exit(1);
53  }
54 }
55 
56 
58 :
59  std::exception(),
60  messageStream(errDict),
61  functionName_(errDict.lookup("functionName")),
62  sourceFileName_(errDict.lookup("sourceFileName")),
63  sourceFileLineNumber_(readLabel(errDict.lookup("sourceFileLineNumber"))),
64  abort_(env("FOAM_ABORT")),
65  throwExceptions_(false),
66  messageStreamPtr_(new OStringStream())
67 {
68  if (!messageStreamPtr_->good())
69  {
70  Perr<< endl
71  << "error::error(const dictionary& errDict) : "
72  "cannot open error stream"
73  << endl;
74  exit(1);
75  }
76 }
77 
78 
80 :
81  std::exception(),
82  messageStream(err),
83  functionName_(err.functionName_),
84  sourceFileName_(err.sourceFileName_),
85  sourceFileLineNumber_(err.sourceFileLineNumber_),
86  abort_(err.abort_),
87  throwExceptions_(err.throwExceptions_),
88  messageStreamPtr_(new OStringStream(*err.messageStreamPtr_))
89 {
90  //*messageStreamPtr_ << err.message();
91 }
92 
93 
95 {
96  delete messageStreamPtr_;
97 }
98 
99 
100 Foam::OSstream& Foam::error::operator()
101 (
102  const char* functionName,
103  const char* sourceFileName,
104  const int sourceFileLineNumber
105 )
106 {
107  functionName_ = functionName;
108  sourceFileName_ = sourceFileName;
109  sourceFileLineNumber_ = sourceFileLineNumber;
110 
111  return operator OSstream&();
112 }
113 
114 
115 Foam::OSstream& Foam::error::operator()
116 (
117  const string& functionName,
118  const char* sourceFileName,
119  const int sourceFileLineNumber
120 )
121 {
122  return operator()
123  (
124  functionName.c_str(),
125  sourceFileName,
126  sourceFileLineNumber
127  );
128 }
129 
130 
131 Foam::error::operator OSstream&()
132 {
133  if (!messageStreamPtr_->good())
134  {
135  Perr<< endl
136  << "error::operator OSstream&() : error stream has failed"
137  << endl;
138  abort();
139  }
140 
141  return *messageStreamPtr_;
142 }
143 
144 
145 Foam::error::operator dictionary() const
146 {
147  dictionary errDict;
148 
149  string oneLineMessage(message());
150  oneLineMessage.replaceAll('\n', ' ');
151 
152  errDict.add("type", word("Foam::error"));
153  errDict.add("message", oneLineMessage);
154  errDict.add("function", functionName());
155  errDict.add("sourceFile", sourceFileName());
156  errDict.add("sourceFileLineNumber", sourceFileLineNumber());
157 
158  return errDict;
159 }
160 
161 
163 {
164  return messageStreamPtr_->str();
165 }
166 
167 
168 void Foam::error::exit(const int errNo)
169 {
170  if (!throwExceptions_ && JobInfo::constructed)
171  {
172  jobInfo.add("FatalError", operator dictionary());
173  jobInfo.exit();
174  }
175 
176  if (abort_)
177  {
178  abort();
179  }
180 
181  if (Pstream::parRun())
182  {
183  Perr<< endl << *this << endl
184  << "\nFOAM parallel run exiting\n" << endl;
185  Pstream::exit(errNo);
186  }
187  else
188  {
189  if (throwExceptions_)
190  {
191  // Make a copy of the error to throw
192  error errorException(*this);
193 
194  // Rewind the message buffer for the next error message
195  messageStreamPtr_->rewind();
196 
197  throw errorException;
198  }
199  else
200  {
201  Perr<< endl << *this << endl
202  << "\nFOAM exiting\n" << endl;
203  ::exit(1);
204  }
205  }
206 }
207 
208 
210 {
211  if (!throwExceptions_ && JobInfo::constructed)
212  {
213  jobInfo.add("FatalError", operator dictionary());
214  jobInfo.abort();
215  }
216 
217  if (abort_)
218  {
219  Perr<< endl << *this << endl
220  << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
221  printStack(Perr);
222  ::abort();
223  }
224 
225  if (Pstream::parRun())
226  {
227  Perr<< endl << *this << endl
228  << "\nFOAM parallel run aborting\n" << endl;
229  printStack(Perr);
230  Pstream::abort();
231  }
232  else
233  {
234  if (throwExceptions_)
235  {
236  // Make a copy of the error to throw
237  error errorException(*this);
238 
239  // Rewind the message buffer for the next error message
240  messageStreamPtr_->rewind();
241 
242  throw errorException;
243  }
244  else
245  {
246  Perr<< endl << *this << endl
247  << "\nFOAM aborting\n" << endl;
248  printStack(Perr);
249  ::abort();
250  }
251  }
252 }
253 
254 
256 {
257  os << endl
258  << fErr.title().c_str() << endl
259  << fErr.message().c_str();
260 
261  if (error::level >= 2 && fErr.sourceFileLineNumber())
262  {
263  os << endl << endl
264  << " From function " << fErr.functionName().c_str() << endl
265  << " in file " << fErr.sourceFileName().c_str()
266  << " at line " << fErr.sourceFileLineNumber() << '.';
267  }
268 
269  return os;
270 }
271 
272 
273 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
274 // Global error definitions
275 
276 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");
277 
278 // ************************ vim: set sw=4 sts=4 et: ************************ //