//# Error.h: Base class for all Casacore errors //# Copyright (C) 1993,1994,1995,1999,2000,2001,2016 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef CASA_ERROR_H #define CASA_ERROR_H #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN // Throw the given exception with a string composed of various arguments. // E.g. // // CASATHROW (AipsError, "integer=" << myint << ", float=" << myfloat); // #define CASATHROW(exc, arg) do { \ std::ostringstream casa_log_oss; \ casa_log_oss << arg; \ throw exc(casa_log_oss.str()); \ } while (0) // The Assert macro is an alias to the standard assert macro when NDEBUG is defined. When // NDEBUG is not defined (release build) then a throw is used to report the error. #ifdef NDEBUG #define AssertCc(c) ((void)0) #else #define AssertCc(c) { if (AIPS_UNLIKELY(! (c))) {casacore::AipsError::throwIf (casacore::True, "Assertion failed: " #c, __FILE__, __LINE__, __PRETTY_FUNCTION__); }} #endif #define AssertAlways(c) { if (AIPS_UNLIKELY(! (c))) {casacore::AipsError::throwIf (casacore::True, "Assertion failed: " #c, __FILE__, __LINE__, __PRETTY_FUNCTION__); }} #define WarnCc(m)\ {\ LogIO os(LogOrigin("", __func__, __LINE__, WHERE));\ os << LogIO::WARN << m << LogIO::POST;\ } // Asserts when in debug build and issues a warning message to the log in release. #if defined (NDEBUG) #define AssertOrWarn(c,m) ((void)0) #else #define AssertOrWarn(c,m)\ { if (AIPS_UNLIKELY(! (c))) {\ WarnCc (m);\ }\ } #endif #if defined (NDEBUG) # define ThrowCc(m) \ { casacore::AipsError anAipsError ((m), __FILE__, __LINE__); \ throw anAipsError; } #else # define ThrowCc(m) throw casacore::AipsError ((m), __FILE__, __LINE__) #endif // Throw an AipsError exception if the condition is true. #define ThrowIf(c,m) {if (AIPS_UNLIKELY(c)) {casacore::AipsError::throwIf (casacore::True, (m), __FILE__, __LINE__, __PRETTY_FUNCTION__);}} // Throw an AipsError exception if the system error code is not 0. // It adds the message for that error code to the exception text. #define ThrowIfError(c,m) {if (AIPS_UNLIKELY(c)) {casacore::AipsError::throwIfError (casacore::True, (m), __FILE__, __LINE__, __PRETTY_FUNCTION__);}} // Repackage and rethrow an AipsError exception. #define Rethrow(e,m) {throw casacore::AipsError::repackageAipsError ((e),(m),__FILE__,__LINE__, __PRETTY_FUNCTION__);} // Base class for all Casacore library errors // // // // // // //
  • ExcpError // // // // This is the base class for all of the Casacore error classes. Because // all of the errors have a common base class, any error can be caught // with a single catch statement. // // This class has a string which allows error messages to be propagated. // // The string member must be handled very carefully because // string is also derived from cleanup, thus the // message.makePermanent() call in the implementation of // the constructors. This prevents the String from being cleaned up // in the middle of an exception. // // // // // // // throw(AipsError("SOME STRING")); // // // // // class AipsError: public std::exception { public: enum Category { BOUNDARY, INITIALIZATION, INVALID_ARGUMENT, CONFORMANCE, ENVIRONMENT, SYSTEM, PERMISSION, GENERAL }; // // Simply returns the stored error message. // virtual const char* what() const noexcept { return(message.c_str()); } const String &getMesg() const { return(message); } String getStackTrace() const; AipsError::Category getCategory( ) const { return(category); } // Append a message. This is used by LogIO when an exception is logged. // The message is const to be able to use it for a temporary exception. void setMessage (const String& msg) const { const_cast(this)->message = msg; } // Creates an AipsError and initializes the error message from // the parameter. // AipsError (const Char *str, Category c = GENERAL); AipsError (const String &str, Category c = GENERAL); AipsError (const String &msg, const String &filename, uInt lineNumber, Category c = GENERAL); AipsError (Category c = GENERAL); // // // Destructor which does nothing. // ~AipsError() noexcept; // Get or clear the stacktrace info. // static void getLastInfo (String & message, String & stackTrace); static String getLastMessage (); static String getLastStackTrace (); static void clearLastInfo (); // // Repackage an exception. static AipsError repackageAipsError (AipsError& error, const String& message, const char* file, Int line, const char* func); // Throw if the condition is true. static void throwIf (Bool condition, const String& message, const char* file, Int line, const char* func = ""); // Throw if the system error code is not 0. static void throwIfError (Int errorCode, const String& prefix, const char* file, Int line, const char* func = ""); protected: // Add the stack trace to the message (if USE_STACKTRACE is set). void addStackTrace (); String message; Category category; String stackTrace; }; // Allocation errors // // // // // // // // This class is used for allocation errors. It adds an extra // data item, the failed allocation size. Otherwise much the // same as AipsError. // // // // // // throw(AllocError("ANY STRING",1024)); // // // // // class AllocError : public AipsError { protected: size_t Size; public: // // This constructor takes the error message and the failed // allocation size. // // AllocError(const Char *str, uInt sze) : AipsError(str,SYSTEM), Size(sze) {} AllocError(const String &str, uInt sze) : AipsError(str,SYSTEM), Size(sze) {} // // // This function returns the failed allocation size. // size_t size() const {return(Size);} // // Destructor which does nothing. // ~AllocError() noexcept; }; // Base class for all indexing errors // // // // // // // This class is the base class of all IndexErrors. It is // defined to allow the user to catch any of the many kinds of IndexErrors // which may be thrown. It can also be thrown itself if returning // the illegal index value is unimportant. // // // // // throw(IndexError("ANY STRING")); // // // // // class IndexError : public AipsError { public: // // Creates an GeneralIndexError and initializes the error message from // the parameter // IndexError(const Char *str,Category c=BOUNDARY) : AipsError(str,c) {} IndexError(const String &str,Category c=BOUNDARY) : AipsError(str,c) {} IndexError(Category c=BOUNDARY) : AipsError(c) {} // // // Destructor which does nothing. // ~IndexError() noexcept; }; // Index errors returning the bad index // // // // // // // This class is templated to allow generalalized indexes to be returned // with the error message i.e. the class is templated on the index type. // // // // // // throw(indexError(3,"ANY STRING"));/ // // // // // template class indexError : public IndexError { protected: t oIndex; // Offending Index public: // // This constructor takes the error message and the index // which cause the error to occur. // // indexError(t oI, const Char *str, Category c=BOUNDARY); indexError(t oI, const String &str, Category c=BOUNDARY); indexError(t oI, Category c=BOUNDARY) : IndexError(c), oIndex(oI) {}; // // // Destructor which does nothing. // ~indexError() noexcept; }; // Duplicate key errors // // // // // // // This class is the base class of all duplicate key errors. It is // defined to allow the user to catch any of the many kinds of DuplErrors // which may be thrown. It can also be thrown itself if returning // the illegal key is unimportant. // // // // // throw(DuplError("ANY STRING")); // // // // // class DuplError : public AipsError { public: // // Creates an DuplError and initializes the error message from // the parameter // DuplError(Category c=BOUNDARY) : AipsError(c) {} DuplError(const Char *str,Category c=BOUNDARY) : AipsError(str,c) {} DuplError(const String &str,Category c=BOUNDARY) : AipsError(str,c) {} // // // Destructor which does nothing. // ~DuplError() noexcept; }; // Duplicate key errors where the bad key is returned // // // // // // // This template is for generalized duplicate key errors where the template // type parameter is the type of the key which caused the error. Because this // class is derived from DuplError // , the user to catch all duplicate key errors with one catch // statement. // // // // // throw(duplError(4,"ANY STRING")); // // // // template class duplError : public DuplError { protected: t oKey; // Offending Key public: // // This constructs a "duplError" for the offending key, and an // optional character string. // // duplError(t oI, const Char *str,Category c=BOUNDARY); duplError(t oI, const String &str,Category c=BOUNDARY); duplError(t oI,Category c=BOUNDARY) : DuplError(c), oKey(oI) {}; // // // Destructor which does nothing. // ~duplError() noexcept; }; // Exception for an error in a system call // // // // // // // This error is to be used for if a system call returns an error. // It uses strerror to get the system error message. // class SystemCallError : public AipsError { public: // This constructs a "SystemCallError" from the system call function name // and the errno. SystemCallError(const String &funcName, int error, Category c=GENERAL); SystemCallError (int error, const String &msg, const String &filename, uInt lineNumber, Category c=GENERAL); // Destructor which does nothing. ~SystemCallError() noexcept; // Get the errno. int error() const { return itsError; } // Get the message belonging to an error. static String errorMessage(int error); private: int itsError; }; // Exception which halts execution // // // // // // // This error causes an execution to halt regardless. It // causes execution to halt before the exception can be caught. // // // // // throw(AbortError("ANY STRING")); // // // // // class AbortError : public AipsError { public: // // This constructs a "AbortError" from the error message. // // AbortError(const Char *str,Category c=GENERAL); AbortError(const String &str,Category c=GENERAL); // // // Destructor which does nothing. // ~AbortError() noexcept; }; // Initialization error, typically of static data shared between objects // // // // // // // This error indicates that some initialization has failed. It is preferable // to throw this in an initX() function called by std::call_once() or similar // over returning a bool or other result variable. // // // // class InitError : public AipsError { }; } //# NAMESPACE CASACORE - END #ifdef AIPS_NEEDS_RETHROW #ifndef CASACORE_NEEDS_RETHROW #define CASACORE_NEEDS_RETHROW #endif #endif #ifdef CASACORE_NEEDS_RETHROW #define RETHROW(X) throw(X); #else #define RETHROW(X) #endif #ifndef CASACORE_NO_AUTO_TEMPLATES #include #endif //# CASACORE_NO_AUTO_TEMPLATES #endif