Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "error.H"
00027 #include <OpenFOAM/OStringStream.H>
00028 #include <OpenFOAM/fileName.H>
00029 #include <OpenFOAM/dictionary.H>
00030 #include <OpenFOAM/JobInfo.H>
00031 #include <OpenFOAM/Pstream.H>
00032 #include <OpenFOAM/OSspecific.H>
00033
00034
00035
00036 Foam::error::error(const string& title)
00037 :
00038 std::exception(),
00039 messageStream(title, messageStream::FATAL),
00040 functionName_("unknown"),
00041 sourceFileName_("unknown"),
00042 sourceFileLineNumber_(0),
00043 abort_(env("FOAM_ABORT")),
00044 throwExceptions_(false),
00045 messageStreamPtr_(new OStringStream())
00046 {
00047 if (!messageStreamPtr_->good())
00048 {
00049 Perr<< endl
00050 << "error::error(const string& title) : cannot open error stream"
00051 << endl;
00052 exit(1);
00053 }
00054 }
00055
00056
00057 Foam::error::error(const dictionary& errDict)
00058 :
00059 std::exception(),
00060 messageStream(errDict),
00061 functionName_(errDict.lookup("functionName")),
00062 sourceFileName_(errDict.lookup("sourceFileName")),
00063 sourceFileLineNumber_(readLabel(errDict.lookup("sourceFileLineNumber"))),
00064 abort_(env("FOAM_ABORT")),
00065 throwExceptions_(false),
00066 messageStreamPtr_(new OStringStream())
00067 {
00068 if (!messageStreamPtr_->good())
00069 {
00070 Perr<< endl
00071 << "error::error(const dictionary& errDict) : "
00072 "cannot open error stream"
00073 << endl;
00074 exit(1);
00075 }
00076 }
00077
00078
00079 Foam::error::error(const error& err)
00080 :
00081 std::exception(),
00082 messageStream(err),
00083 functionName_(err.functionName_),
00084 sourceFileName_(err.sourceFileName_),
00085 sourceFileLineNumber_(err.sourceFileLineNumber_),
00086 abort_(err.abort_),
00087 throwExceptions_(err.throwExceptions_),
00088 messageStreamPtr_(new OStringStream(*err.messageStreamPtr_))
00089 {
00090
00091 }
00092
00093
00094 Foam::error::~error() throw()
00095 {
00096 delete messageStreamPtr_;
00097 }
00098
00099
00100 Foam::OSstream& Foam::error::operator()
00101 (
00102 const char* functionName,
00103 const char* sourceFileName,
00104 const int sourceFileLineNumber
00105 )
00106 {
00107 functionName_ = functionName;
00108 sourceFileName_ = sourceFileName;
00109 sourceFileLineNumber_ = sourceFileLineNumber;
00110
00111 return operator OSstream&();
00112 }
00113
00114
00115 Foam::OSstream& Foam::error::operator()
00116 (
00117 const string& functionName,
00118 const char* sourceFileName,
00119 const int sourceFileLineNumber
00120 )
00121 {
00122 return operator()
00123 (
00124 functionName.c_str(),
00125 sourceFileName,
00126 sourceFileLineNumber
00127 );
00128 }
00129
00130
00131 Foam::error::operator OSstream&()
00132 {
00133 if (!messageStreamPtr_->good())
00134 {
00135 Perr<< endl
00136 << "error::operator OSstream&() : error stream has failed"
00137 << endl;
00138 abort();
00139 }
00140
00141 return *messageStreamPtr_;
00142 }
00143
00144
00145 Foam::error::operator dictionary() const
00146 {
00147 dictionary errDict;
00148
00149 string oneLineMessage(message());
00150 oneLineMessage.replaceAll('\n', ' ');
00151
00152 errDict.add("type", word("Foam::error"));
00153 errDict.add("message", oneLineMessage);
00154 errDict.add("function", functionName());
00155 errDict.add("sourceFile", sourceFileName());
00156 errDict.add("sourceFileLineNumber", sourceFileLineNumber());
00157
00158 return errDict;
00159 }
00160
00161
00162 Foam::string Foam::error::message() const
00163 {
00164 return messageStreamPtr_->str();
00165 }
00166
00167
00168 void Foam::error::exit(const int errNo)
00169 {
00170 if (!throwExceptions_ && JobInfo::constructed)
00171 {
00172 jobInfo.add("FatalError", operator dictionary());
00173 jobInfo.exit();
00174 }
00175
00176 if (abort_)
00177 {
00178 abort();
00179 }
00180
00181 if (Pstream::parRun())
00182 {
00183 Perr<< endl << *this << endl
00184 << "\nFOAM parallel run exiting\n" << endl;
00185 Pstream::exit(errNo);
00186 }
00187 else
00188 {
00189 if (throwExceptions_)
00190 {
00191
00192 error errorException(*this);
00193
00194
00195 messageStreamPtr_->rewind();
00196
00197 throw errorException;
00198 }
00199 else
00200 {
00201 Perr<< endl << *this << endl
00202 << "\nFOAM exiting\n" << endl;
00203 ::exit(1);
00204 }
00205 }
00206 }
00207
00208
00209 void Foam::error::abort()
00210 {
00211 if (!throwExceptions_ && JobInfo::constructed)
00212 {
00213 jobInfo.add("FatalError", operator dictionary());
00214 jobInfo.abort();
00215 }
00216
00217 if (abort_)
00218 {
00219 Perr<< endl << *this << endl
00220 << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
00221 printStack(Perr);
00222 ::abort();
00223 }
00224
00225 if (Pstream::parRun())
00226 {
00227 Perr<< endl << *this << endl
00228 << "\nFOAM parallel run aborting\n" << endl;
00229 printStack(Perr);
00230 Pstream::abort();
00231 }
00232 else
00233 {
00234 if (throwExceptions_)
00235 {
00236
00237 error errorException(*this);
00238
00239
00240 messageStreamPtr_->rewind();
00241
00242 throw errorException;
00243 }
00244 else
00245 {
00246 Perr<< endl << *this << endl
00247 << "\nFOAM aborting\n" << endl;
00248 printStack(Perr);
00249 ::abort();
00250 }
00251 }
00252 }
00253
00254
00255 Foam::Ostream& Foam::operator<<(Ostream& os, const error& fErr)
00256 {
00257 os << endl
00258 << fErr.title().c_str() << endl
00259 << fErr.message().c_str();
00260
00261 if (error::level >= 2 && fErr.sourceFileLineNumber())
00262 {
00263 os << endl << endl
00264 << " From function " << fErr.functionName().c_str() << endl
00265 << " in file " << fErr.sourceFileName().c_str()
00266 << " at line " << fErr.sourceFileLineNumber() << '.';
00267 }
00268
00269 return os;
00270 }
00271
00272
00273
00274
00275
00276 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");
00277
00278