casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Error.h
Go to the documentation of this file.
00001 //# Error.h: Base class for all AIPS++ errors
00002 //# Copyright (C) 1993,1994,1995,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: Error.h 21051 2011-04-20 11:46:29Z gervandiepen $
00027 
00028 #ifndef CASA_ERROR_H
00029 #define CASA_ERROR_H
00030 
00031 
00032 
00033 #include <sys/types.h>
00034 #include <casa/aips.h>
00035 #include <casa/BasicSL/String.h>
00036 #include <casa/OS/Mutex.h>
00037 #include <exception>
00038 
00039 
00040 namespace casa { //# NAMESPACE CASA - BEGIN
00041 
00042 // Throw an exception with a string composed of various arguments.
00043 // E.g.
00044 // <srcblock>
00045 //    CASATHROW (AipsError, "integer=" << myint << ", float=" << myfloat)
00046 // </srcblock>
00047 #define CASATHROW(exc, arg) do {     \
00048     std::ostringstream casa_log_oss; \
00049     casa_log_oss << arg;             \
00050     throw exc(casa_log_oss.str());   \
00051   } while (0)
00052 
00053 
00054 // <summary>Base class for all AIPS++ library errors</summary>
00055 // <use visibility=export>
00056 //
00057 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00058 // </reviewed>
00059 //
00060 // <prerequisite>
00061 //   <li> ExcpError
00062 // </prerequisite>
00063 //
00064 // <synopsis>
00065 //  This is the base class for all of the AIPS++ error classes. Because
00066 //  all of the errors have a common base class, any error can be caught
00067 //  with a single catch statement.
00068 //
00069 //  This class has a string which allows error messages to be propagated.
00070 //
00071 //  <note role=tip> The string member must be handled very carefully because
00072 //        string is also derived from cleanup, thus the 
00073 //        <src>message.makePermanent()</src> call in the implementation of
00074 //        the constructors. This prevents the String from being cleaned up
00075 //        in the middle of an exception.
00076 //  </note>
00077 //
00078 // </synopsis>
00079 //
00080 // <example>
00081 // <srcblock>
00082 //      throw(AipsError("SOME STRING"));
00083 // </srcblock>
00084 // </example>
00085 //
00086 // <todo asof="">
00087 // </todo>
00088 
00089 class AipsError: public std::exception
00090 {
00091 public:
00092 
00093   enum Category {
00094     BOUNDARY, INITIALIZATION, INVALID_ARGUMENT, CONFORMANCE,
00095     ENVIRONMENT, SYSTEM, PERMISSION, GENERAL
00096   };
00097 
00098   //
00099   // Simply returns the stored error message.
00100   //
00101   virtual const char* what() const throw()
00102     { return(message.c_str()); }
00103   const String &getMesg() const
00104     { return(message); }
00105   String getStackTrace () const;
00106   AipsError::Category getCategory( ) const
00107     { return(category); }
00108 
00109   // Append a message. This is used by LogIO when an exception is logged.
00110   // The message is const to be able to use it for a temporary exception.
00111   void setMessage (const String& msg) const
00112     { const_cast<AipsError*>(this)->message = msg; }
00113 
00114   // Creates an AipsError and initializes the error message from
00115   // the parameter.
00116   // <group>
00117   AipsError (const Char *str, Category c = GENERAL);
00118   AipsError (const String &str, Category c = GENERAL);
00119   AipsError (const String &msg, const String &filename, uInt lineNumber,
00120              Category c = GENERAL);
00121   AipsError (Category c = GENERAL);
00122   // </group>
00123 
00124   //
00125   // Destructor which does nothing.
00126   //
00127   ~AipsError() throw();
00128 
00129   static String generateStackTrace ();
00130 
00131   static void getLastInfo (String & message, String & stackTrace);
00132   static String getLastMessage ();
00133   static String getLastStackTrace ();
00134   static void clearLastInfo ();
00135   static String noMessage ();
00136   static String noStackTrace ();
00137 
00138 protected:
00139 
00140   void addStackTrace ();
00141 
00142   String message;
00143   Category category;
00144   String stackTrace;
00145 
00146   static String lastMessage;    // error message from last exception
00147   static String lastStackTrace; // stack trace from last exception
00148   static Mutex  lastErrorMutex; // protects the lastMessage and lastStackTrace statics
00149 };
00150 
00151 
00152 // <summary>Allocation errors</summary>
00153 // <use visibility=export>
00154 //
00155 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00156 // </reviewed>
00157 //
00158 // <synopsis>
00159 //
00160 // This class is used for allocation errors. It adds an extra
00161 // data item, the failed allocation size. Otherwise much the
00162 // same as <src>AipsError</src>.
00163 //
00164 // </synopsis>
00165 //
00166 // <example>
00167 // <srcblock>
00168 //     throw(AllocError("ANY STRING",1024));
00169 // </srcblock>
00170 // </example>
00171 //
00172 // <todo asof="">
00173 // </todo>
00174 
00175 class AllocError : public AipsError {
00176 protected:
00177   size_t Size;
00178 public:
00179   //
00180   // This constructor takes the error message and the failed
00181   // allocation size.
00182   //
00183   // <group>
00184   AllocError(const Char *str, uInt sze) : AipsError(str,SYSTEM), Size(sze) {}
00185   AllocError(const String &str, uInt sze) : AipsError(str,SYSTEM), Size(sze)  {}
00186   // </group>
00187 
00188   //
00189   // This function returns the failed allocation size.
00190   //
00191   size_t size() const {return(Size);}
00192 
00193   //
00194   // Destructor which does nothing.
00195   //
00196   ~AllocError() throw();
00197 
00198 };
00199 
00200 
00201 // <summary>Base class for all indexing errors</summary>
00202 // <use visibility=export>
00203 //
00204 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00205 // </reviewed>
00206 //
00207 // <synopsis>
00208 // This class is the base class of all <src>IndexError</src>s. It is
00209 // defined to allow the user to catch any of the many kinds of IndexErrors
00210 // which may be thrown. It can also be thrown itself if returning
00211 // the illegal index value is unimportant.
00212 // </synopsis>
00213 //
00214 // <example>
00215 // <srcblock>
00216 //     throw(IndexError("ANY STRING"));
00217 // </srcblock>
00218 // </example>
00219 //
00220 // <todo asof="">
00221 // </todo>
00222 
00223 class IndexError : public AipsError {
00224 public:
00225   //
00226   // Creates an GeneralIndexError and initializes the error message from
00227   // the parameter
00228   // <group>
00229   IndexError(const Char *str,Category c=BOUNDARY) : AipsError(str,c) {}
00230   IndexError(const String &str,Category c=BOUNDARY) : AipsError(str,c) {}
00231   IndexError(Category c=BOUNDARY) : AipsError(c) {}
00232   // </group>
00233 
00234   //
00235   // Destructor which does nothing.
00236   //
00237   ~IndexError() throw();
00238 };
00239 
00240 
00241 // <summary>Index errors returning the bad index</summary>
00242 // <use visibility=export>
00243 //
00244 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00245 // </reviewed>
00246 //
00247 // <synopsis>
00248 // This class is templated to allow generalalized indexes to be returned
00249 // with the error message i.e. the class is templated on the index type.
00250 //
00251 // </synopsis>
00252 //
00253 // <example>
00254 // <srcblock>
00255 //     throw(indexError<int>(3,"ANY STRING"));/
00256 // </srcblock>
00257 // </example>
00258 //
00259 // <todo asof="">
00260 // </todo>
00261 
00262 template<class t> class indexError : public IndexError {
00263 protected:
00264   t oIndex;                 // Offending Index
00265 public:
00266   //
00267   // This constructor takes the error message and the index
00268   // which cause the error to occur.
00269   //
00270   // <group>
00271   indexError(t oI, const Char *str, Category c=BOUNDARY);
00272   indexError(t oI, const String &str, Category c=BOUNDARY);
00273   indexError(t oI, Category c=BOUNDARY) : IndexError(c), oIndex(oI) {};
00274   // </group>
00275 
00276   //
00277   // Destructor which does nothing.
00278   //
00279   ~indexError() throw();
00280 };
00281 
00282 
00283 // <summary>Duplicate key errors</summary>
00284 // <use visibility=export>
00285 //
00286 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00287 // </reviewed>
00288 //
00289 // <synopsis>
00290 // This class is the base class of all duplicate key errors. It is
00291 // defined to allow the user to catch any of the many kinds of DuplErrors
00292 // which may be thrown. It can also be thrown itself if returning
00293 // the illegal key is unimportant.
00294 // </synopsis>
00295 //
00296 // <example>
00297 // <srcblock>
00298 //    throw(DuplError("ANY STRING"));
00299 // </srcblock>
00300 // </example>
00301 //
00302 // <todo asof="">
00303 // </todo>
00304 
00305 class DuplError : public AipsError {
00306 public:
00307   //
00308   // Creates an DuplError and initializes the error message from
00309   // the parameter
00310   // <group>
00311   DuplError(Category c=BOUNDARY) : AipsError(c) {}
00312   DuplError(const Char *str,Category c=BOUNDARY) : AipsError(str,c) {}
00313   DuplError(const String &str,Category c=BOUNDARY) : AipsError(str,c) {}
00314   // </group>
00315 
00316   //
00317   // Destructor which does nothing.
00318   //
00319   ~DuplError() throw();
00320 };
00321 
00322 
00323 // <summary>Duplicate key errors where the bad key is returned</summary>
00324 // <use visibility=export>
00325 //
00326 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00327 // </reviewed>
00328 //
00329 // <synopsis>
00330 //  This template is for generalized duplicate key errors where the template
00331 //  type parameter is the type of the key which caused the error. Because this
00332 //  class is derived from <linkto class=DuplError><src>DuplError</src>
00333 //  </linkto>, the user to catch all duplicate key errors with one catch
00334 //  statement. 
00335 //
00336 // </synopsis>
00337 //
00338 // <example>
00339 //     throw(duplError<int>(4,"ANY STRING"));
00340 // </example>
00341 //
00342 // <todo asof="">
00343 // </todo>
00344 
00345 template<class t> class duplError : public DuplError {
00346 protected:
00347   t oKey;                   // Offending Key
00348 public:
00349   //
00350   // This constructs a "duplError" for the offending key, and an
00351   // optional character string.
00352   //
00353   // <group>
00354   duplError(t oI, const Char *str,Category c=BOUNDARY);
00355   duplError(t oI, const String &str,Category c=BOUNDARY);
00356   duplError(t oI,Category c=BOUNDARY) : DuplError(c), oKey(oI) {};
00357   // </group>
00358 
00359   //
00360   // Destructor which does nothing.
00361   //
00362   ~duplError() throw();
00363 };
00364 
00365 
00366 // <summary>Exception for an error in a system call</summary>
00367 // <use visibility=export>
00368 //
00369 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00370 // </reviewed>
00371 //
00372 // <synopsis>
00373 // This error is to be used for if a system call returns an error.
00374 // It uses strerror to get the system error message.
00375 // </synopsis>
00376 
00377 class SystemCallError : public AipsError
00378 {
00379 public:
00380   // This constructs a "SystemCallError" from the system call function name
00381   // and the errno.
00382   SystemCallError(const String &funcName, int error, Category c=GENERAL);
00383 
00384   // Destructor which does nothing.
00385   ~SystemCallError() throw();
00386 
00387   // Get the errno.
00388   int error() const
00389     { return itsError; }
00390 
00391   // Get the message belonging to an error.
00392   static String errorMessage(int error);
00393 
00394 private:
00395   int itsError;
00396 };
00397 
00398 
00399 // <summary>Exception which halts execution</summary>
00400 // <use visibility=export>
00401 //
00402 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00403 // </reviewed>
00404 //
00405 // <synopsis>
00406 // This error causes an execution to halt regardless. It
00407 // causes execution to halt before the exception can be caught.
00408 // </synopsis>
00409 //
00410 // <example>
00411 // <srcblock>
00412 //     throw(AbortError("ANY STRING"));
00413 // </srcblock>
00414 // </example>
00415 //
00416 // <todo asof="">
00417 // </todo>
00418 
00419 class AbortError : public AipsError {
00420 public:
00421   //
00422   // This constructs a "AbortError" from the error message.
00423   //
00424   // <group>
00425   AbortError(const Char *str,Category c=GENERAL);
00426   AbortError(const String &str,Category c=GENERAL);
00427   // </group>
00428 
00429   //
00430   // Destructor which does nothing.
00431   //
00432   ~AbortError() throw();
00433 };
00434 
00435 
00436 
00437 } //# NAMESPACE CASA - END
00438 
00439 #ifdef AIPS_NEEDS_RETHROW
00440 #ifndef CASACORE_NEEDS_RETHROW
00441 #define CASACORE_NEEDS_RETHROW
00442 #endif
00443 #endif
00444 
00445 #ifdef CASACORE_NEEDS_RETHROW
00446 #define RETHROW(X) throw(X);
00447 #else
00448 #define RETHROW(X)
00449 #endif
00450 
00451 #ifndef CASACORE_NO_AUTO_TEMPLATES
00452 #include <casa/Exceptions/Error.tcc>
00453 #endif //# CASACORE_NO_AUTO_TEMPLATES
00454 #endif