casa
$Rev:20696$
|
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