Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / db / error / error.C
blobc4d4d5817e1b307b4a4ebbb0546b934a98d6e75f
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
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"
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 Foam::error::error(const string& title)
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())
47     if (!messageStreamPtr_->good())
48     {
49         Perr<< endl
50             << "error::error(const string& title) : cannot open error stream"
51             << endl;
52         exit(1);
53     }
57 Foam::error::error(const dictionary& errDict)
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())
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     }
79 Foam::error::error(const error& err)
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_))
90     //*messageStreamPtr_ << err.message();
94 Foam::error::~error() throw()
96     delete messageStreamPtr_;
100 Foam::OSstream& Foam::error::operator()
102     const char* functionName,
103     const char* sourceFileName,
104     const int sourceFileLineNumber
107     functionName_ = functionName;
108     sourceFileName_ = sourceFileName;
109     sourceFileLineNumber_ = sourceFileLineNumber;
111     return operator OSstream&();
115 Foam::OSstream& Foam::error::operator()
117     const string& functionName,
118     const char* sourceFileName,
119     const int sourceFileLineNumber
122     return operator()
123     (
124         functionName.c_str(),
125         sourceFileName,
126         sourceFileLineNumber
127     );
131 Foam::error::operator OSstream&()
133     if (!messageStreamPtr_->good())
134     {
135         Perr<< endl
136             << "error::operator OSstream&() : error stream has failed"
137             << endl;
138         abort();
139     }
141     return *messageStreamPtr_;
145 Foam::error::operator dictionary() const
147     dictionary errDict;
149     string oneLineMessage(message());
150     oneLineMessage.replaceAll('\n', ' ');
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());
158     return errDict;
162 Foam::string Foam::error::message() const
164     return messageStreamPtr_->str();
168 void Foam::error::exit(const int errNo)
170     if (!throwExceptions_ && JobInfo::constructed)
171     {
172         jobInfo.add("FatalError", operator dictionary());
173         jobInfo.exit();
174     }
176     if (abort_)
177     {
178         Perr<< endl << *this << endl
179             << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
181         abort();
182     }
184     if (Pstream::parRun())
185     {
186         Perr<< endl << *this << endl
187             << "\nFOAM parallel run exiting\n" << endl;
188         Pstream::exit(errNo);
189     }
190     else
191     {
192         if (throwExceptions_)
193         {
194             // Make a copy of the error to throw
195             error errorException(*this);
197             // Rewind the message buffer for the next error message
198             messageStreamPtr_->rewind();
200             throw errorException;
201         }
202         else
203         {
204             Perr<< endl << *this << endl
205                 << "\nFOAM exiting\n" << endl;
206             ::exit(1);
207         }
208     }
212 void Foam::error::abort()
214     if (!throwExceptions_ && JobInfo::constructed)
215     {
216         jobInfo.add("FatalError", operator dictionary());
217         jobInfo.abort();
218     }
220     if (abort_)
221     {
222         Perr<< endl << *this << endl
223             << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
224         printStack(Perr);
225         ::abort();
226     }
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             error errorException(*this);
242             // Rewind the message buffer for the next error message
243             messageStreamPtr_->rewind();
245             throw errorException;
246         }
247         else
248         {
249             Perr<< endl << *this << endl
250                 << "\nFOAM aborting\n" << endl;
251             printStack(Perr);
252             ::abort();
253         }
254     }
258 Foam::Ostream& Foam::operator<<(Ostream& os, const error& fErr)
260     os  << endl
261         << fErr.title().c_str() << endl
262         << fErr.message().c_str();
264     if (error::level >= 2 && fErr.sourceFileLineNumber())
265     {
266         os  << endl << endl
267             << "    From function " << fErr.functionName().c_str() << endl
268             << "    in file " << fErr.sourceFileName().c_str()
269             << " at line " << fErr.sourceFileLineNumber() << '.';
270     }
272     return os;
276 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
277 // Global error definitions
279 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");
281 // ************************************************************************* //