mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve abort/exception handling in error class (#1780)
- previously setting FOAM_ABORT would preempt checks for throwing exceptions. Now check for throwing first, to allow try/catch code to do its job. However, ignore exception throwing for abort(). These are used infrequently in the code, but indicate that recovery is deemed impossible. STYLE: use unique_ptr for internal stream buffer management
This commit is contained in:
@ -170,14 +170,14 @@ Foam::IOerror::operator Foam::dictionary() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::IOerror::exitOrAbort(const int, const bool isAbort)
|
void Foam::IOerror::exitOrAbort(const int errNo, const bool isAbort)
|
||||||
{
|
{
|
||||||
if (!throwExceptions_ && JobInfo::constructed)
|
if (!throwing_ && JobInfo::constructed)
|
||||||
{
|
{
|
||||||
jobInfo.add("FatalIOError", operator dictionary());
|
jobInfo.add("FatalIOError", operator dictionary());
|
||||||
if (isAbort)
|
if (isAbort || hasEnv("FOAM_ABORT"))
|
||||||
{
|
{
|
||||||
jobInfo.abort();
|
jobInfo.abort();
|
||||||
}
|
}
|
||||||
@ -187,14 +187,7 @@ void Foam::IOerror::exitOrAbort(const int, const bool isAbort)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasEnv("FOAM_ABORT"))
|
if (throwing_ && !isAbort)
|
||||||
{
|
|
||||||
Perr<< nl << *this << nl
|
|
||||||
<< "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
|
|
||||||
printStack(Perr);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
else if (throwExceptions_)
|
|
||||||
{
|
{
|
||||||
// Make a copy of the error to throw
|
// Make a copy of the error to throw
|
||||||
IOerror errorException(*this);
|
IOerror errorException(*this);
|
||||||
@ -204,20 +197,27 @@ void Foam::IOerror::exitOrAbort(const int, const bool isAbort)
|
|||||||
|
|
||||||
throw errorException;
|
throw errorException;
|
||||||
}
|
}
|
||||||
|
else if (hasEnv("FOAM_ABORT"))
|
||||||
|
{
|
||||||
|
Perr<< nl << *this << nl
|
||||||
|
<< "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
|
||||||
|
error::printStack(Perr);
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
else if (Pstream::parRun())
|
else if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
if (isAbort)
|
if (isAbort)
|
||||||
{
|
{
|
||||||
Perr<< nl << *this << nl
|
Perr<< nl << *this << nl
|
||||||
<< "\nFOAM parallel run aborting\n" << endl;
|
<< "\nFOAM parallel run aborting\n" << endl;
|
||||||
printStack(Perr);
|
error::printStack(Perr);
|
||||||
Pstream::abort();
|
Pstream::abort();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Perr<< nl << *this << nl
|
Perr<< nl << *this << nl
|
||||||
<< "\nFOAM parallel run exiting\n" << endl;
|
<< "\nFOAM parallel run exiting\n" << endl;
|
||||||
Pstream::exit(1);
|
Pstream::exit(errNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -226,7 +226,7 @@ void Foam::IOerror::exitOrAbort(const int, const bool isAbort)
|
|||||||
{
|
{
|
||||||
Perr<< nl << *this << nl
|
Perr<< nl << *this << nl
|
||||||
<< "\nFOAM aborting\n" << endl;
|
<< "\nFOAM aborting\n" << endl;
|
||||||
printStack(Perr);
|
error::printStack(Perr);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::exit(1); // Prefer exit() to avoid unnecessary warnings
|
std::exit(1); // Prefer exit() to avoid unnecessary warnings
|
||||||
@ -238,15 +238,17 @@ void Foam::IOerror::exitOrAbort(const int, const bool isAbort)
|
|||||||
{
|
{
|
||||||
Perr<< nl << *this << nl
|
Perr<< nl << *this << nl
|
||||||
<< "\nFOAM exiting\n" << endl;
|
<< "\nFOAM exiting\n" << endl;
|
||||||
std::exit(1);
|
std::exit(errNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::IOerror::exit(const int)
|
void Foam::IOerror::exit(const int)
|
||||||
{
|
{
|
||||||
exitOrAbort(1, hasEnv("FOAM_ABORT"));
|
exitOrAbort(1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -79,17 +79,9 @@ Foam::error::error(const string& title)
|
|||||||
functionName_("unknown"),
|
functionName_("unknown"),
|
||||||
sourceFileName_("unknown"),
|
sourceFileName_("unknown"),
|
||||||
sourceFileLineNumber_(0),
|
sourceFileLineNumber_(0),
|
||||||
throwExceptions_(false),
|
throwing_(false),
|
||||||
messageStreamPtr_(new OStringStream())
|
messageStreamPtr_(new OStringStream())
|
||||||
{
|
{}
|
||||||
if (!messageStreamPtr_->good())
|
|
||||||
{
|
|
||||||
Perr<< nl
|
|
||||||
<< "error::error(const string&) : cannot open error stream"
|
|
||||||
<< endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::error::error(const dictionary& errDict)
|
Foam::error::error(const dictionary& errDict)
|
||||||
@ -99,17 +91,9 @@ Foam::error::error(const dictionary& errDict)
|
|||||||
functionName_(errDict.get<string>("functionName")),
|
functionName_(errDict.get<string>("functionName")),
|
||||||
sourceFileName_(errDict.get<string>("sourceFileName")),
|
sourceFileName_(errDict.get<string>("sourceFileName")),
|
||||||
sourceFileLineNumber_(errDict.get<label>("sourceFileLineNumber")),
|
sourceFileLineNumber_(errDict.get<label>("sourceFileLineNumber")),
|
||||||
throwExceptions_(false),
|
throwing_(false),
|
||||||
messageStreamPtr_(new OStringStream())
|
messageStreamPtr_(new OStringStream())
|
||||||
{
|
{}
|
||||||
if (!messageStreamPtr_->good())
|
|
||||||
{
|
|
||||||
Perr<< nl
|
|
||||||
<< "error::error(const dictionary&) : cannot open error stream"
|
|
||||||
<< endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::error::error(const error& err)
|
Foam::error::error(const error& err)
|
||||||
@ -119,7 +103,7 @@ Foam::error::error(const error& err)
|
|||||||
functionName_(err.functionName_),
|
functionName_(err.functionName_),
|
||||||
sourceFileName_(err.sourceFileName_),
|
sourceFileName_(err.sourceFileName_),
|
||||||
sourceFileLineNumber_(err.sourceFileLineNumber_),
|
sourceFileLineNumber_(err.sourceFileLineNumber_),
|
||||||
throwExceptions_(err.throwExceptions_),
|
throwing_(err.throwing_),
|
||||||
messageStreamPtr_(new OStringStream(*err.messageStreamPtr_))
|
messageStreamPtr_(new OStringStream(*err.messageStreamPtr_))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -127,9 +111,7 @@ Foam::error::error(const error& err)
|
|||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::error::~error() noexcept
|
Foam::error::~error() noexcept
|
||||||
{
|
{}
|
||||||
delete messageStreamPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
@ -208,27 +190,14 @@ Foam::error::operator Foam::dictionary() const
|
|||||||
return errDict;
|
return errDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::string Foam::error::message() const
|
|
||||||
{
|
|
||||||
return messageStreamPtr_->str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::error::clear() const
|
|
||||||
{
|
|
||||||
return messageStreamPtr_->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::error::exitOrAbort(const int errNo, const bool isAbort)
|
void Foam::error::exitOrAbort(const int errNo, const bool isAbort)
|
||||||
{
|
{
|
||||||
if (!throwExceptions_ && JobInfo::constructed)
|
if (!throwing_ && JobInfo::constructed)
|
||||||
{
|
{
|
||||||
jobInfo.add("FatalError", operator dictionary());
|
jobInfo.add("FatalError", operator dictionary());
|
||||||
if (isAbort)
|
if (isAbort || hasEnv("FOAM_ABORT"))
|
||||||
{
|
{
|
||||||
jobInfo.abort();
|
jobInfo.abort();
|
||||||
}
|
}
|
||||||
@ -238,14 +207,7 @@ void Foam::error::exitOrAbort(const int errNo, const bool isAbort)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasEnv("FOAM_ABORT"))
|
if (throwing_ && !isAbort)
|
||||||
{
|
|
||||||
Perr<< nl << *this << nl
|
|
||||||
<< "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
|
|
||||||
printStack(Perr);
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
else if (throwExceptions_)
|
|
||||||
{
|
{
|
||||||
// Make a copy of the error to throw
|
// Make a copy of the error to throw
|
||||||
error errorException(*this);
|
error errorException(*this);
|
||||||
@ -255,13 +217,20 @@ void Foam::error::exitOrAbort(const int errNo, const bool isAbort)
|
|||||||
|
|
||||||
throw errorException;
|
throw errorException;
|
||||||
}
|
}
|
||||||
|
else if (hasEnv("FOAM_ABORT"))
|
||||||
|
{
|
||||||
|
Perr<< nl << *this << nl
|
||||||
|
<< "\nFOAM aborting (FOAM_ABORT set)\n" << endl;
|
||||||
|
error::printStack(Perr);
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
else if (Pstream::parRun())
|
else if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
if (isAbort)
|
if (isAbort)
|
||||||
{
|
{
|
||||||
Perr<< nl << *this << nl
|
Perr<< nl << *this << nl
|
||||||
<< "\nFOAM parallel run aborting\n" << endl;
|
<< "\nFOAM parallel run aborting\n" << endl;
|
||||||
printStack(Perr);
|
error::printStack(Perr);
|
||||||
Pstream::abort();
|
Pstream::abort();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -277,7 +246,7 @@ void Foam::error::exitOrAbort(const int errNo, const bool isAbort)
|
|||||||
{
|
{
|
||||||
Perr<< nl << *this << nl
|
Perr<< nl << *this << nl
|
||||||
<< "\nFOAM aborting\n" << endl;
|
<< "\nFOAM aborting\n" << endl;
|
||||||
printStack(Perr);
|
error::printStack(Perr);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::exit(1); // Prefer exit() to avoid unnecessary warnings
|
std::exit(1); // Prefer exit() to avoid unnecessary warnings
|
||||||
@ -295,9 +264,23 @@ void Foam::error::exitOrAbort(const int errNo, const bool isAbort)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::string Foam::error::message() const
|
||||||
|
{
|
||||||
|
return messageStreamPtr_->str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::error::clear() const
|
||||||
|
{
|
||||||
|
return messageStreamPtr_->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::error::exit(const int errNo)
|
void Foam::error::exit(const int errNo)
|
||||||
{
|
{
|
||||||
exitOrAbort(errNo, hasEnv("FOAM_ABORT"));
|
exitOrAbort(errNo, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,11 @@ Usage
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
error.C
|
error.C
|
||||||
|
IOerror.C
|
||||||
|
|
||||||
|
SeeAlso
|
||||||
|
Foam::errorManip
|
||||||
|
Foam::errorManipArg
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -52,6 +57,7 @@ SourceFiles
|
|||||||
#define error_H
|
#define error_H
|
||||||
|
|
||||||
#include "messageStream.H"
|
#include "messageStream.H"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -80,8 +86,8 @@ protected:
|
|||||||
string functionName_;
|
string functionName_;
|
||||||
string sourceFileName_;
|
string sourceFileName_;
|
||||||
label sourceFileLineNumber_;
|
label sourceFileLineNumber_;
|
||||||
bool throwExceptions_;
|
bool throwing_;
|
||||||
OStringStream* messageStreamPtr_;
|
std::unique_ptr<OStringStream> messageStreamPtr_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -138,15 +144,15 @@ public:
|
|||||||
//- Return the current exception throwing (on or off)
|
//- Return the current exception throwing (on or off)
|
||||||
bool throwing() const
|
bool throwing() const
|
||||||
{
|
{
|
||||||
return throwExceptions_;
|
return throwing_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Activate/deactivate exception throwing
|
//- Activate/deactivate exception throwing
|
||||||
// \return the previous throwing state
|
// \return the previous throwing state
|
||||||
inline bool throwExceptions(bool doThrow)
|
inline bool throwExceptions(bool doThrow)
|
||||||
{
|
{
|
||||||
const bool prev = throwExceptions_;
|
const bool prev = throwing_;
|
||||||
throwExceptions_ = doThrow;
|
throwing_ = doThrow;
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -135,13 +135,6 @@ exit(error& err, const int errNo = 1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline errorManip<error>
|
|
||||||
abort(error& err)
|
|
||||||
{
|
|
||||||
return errorManip<error>(&error::abort, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline errorManipArg<IOerror, int>
|
inline errorManipArg<IOerror, int>
|
||||||
exit(IOerror& err, const int errNo = 1)
|
exit(IOerror& err, const int errNo = 1)
|
||||||
{
|
{
|
||||||
@ -149,6 +142,13 @@ exit(IOerror& err, const int errNo = 1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline errorManip<error>
|
||||||
|
abort(error& err)
|
||||||
|
{
|
||||||
|
return errorManip<error>(&error::abort, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline errorManip<IOerror>
|
inline errorManip<IOerror>
|
||||||
abort(IOerror& err)
|
abort(IOerror& err)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user