FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

error.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
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     //*messageStreamPtr_ << err.message();
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             // Make a copy of the error to throw
00192             error errorException(*this);
00193 
00194             // Rewind the message buffer for the next error message
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             // Make a copy of the error to throw
00237             error errorException(*this);
00238 
00239             // Rewind the message buffer for the next error message
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 // Global error definitions
00275 
00276 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");
00277 
00278 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines