00001 /* 00002 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. 00003 * 00004 * Licensed under the Universal Permissive License v 1.0 as shown at 00005 * http://oss.oracle.com/licenses/upl. 00006 */ 00007 #ifndef COH_EXCEPTION_HPP 00008 #define COH_EXCEPTION_HPP 00009 00010 #include "coherence/lang/compatibility.hpp" 00011 00012 #include "coherence/lang/throwable_spec.hpp" 00013 #include "coherence/lang/FinalView.hpp" 00014 #include "coherence/lang/ObjectArray.hpp" 00015 #include "coherence/lang/String.hpp" 00016 #include "coherence/lang/TypedHandle.hpp" 00017 #include "coherence/lang/TypedHolder.hpp" 00018 00019 #include <stdexcept> 00020 00021 COH_OPEN_NAMESPACE2(coherence,lang) 00022 00023 00024 /** 00025 * Base class for all exceptions used in Coherence. 00026 * 00027 * Exceptions are not thrown directly, but rather via the COH_THROW macro. The 00028 * macro will record the stack trace and throw the managed Exception such that 00029 * it may be caught either via its View type, or as a std::exception derivative. 00030 * Unlike standard C++ exceptions, managed exceptions may be caught by value, 00031 * i.e. not using a const& and still be safely re-thrown 00032 * (via the COH_THROW macro) without risking object slicing. This allows caught 00033 * exceptions to be stored as data member or local variables outside of a 00034 * try/catch block and to be safely re-thrown at a later time. 00035 * 00036 * New exception classes are declared using the throwable_spec<> helper template. 00037 * 00038 * @code 00039 * try 00040 * { 00041 * ... 00042 * COH_THROW (IOException::create("some error")); 00043 * ... 00044 * } 00045 * catch (IOException::View vIoe) 00046 * { 00047 * std::cerr << vIoe << std::endl; 00048 * ... 00049 * } 00050 * catch (Exception::View vEx) 00051 * { 00052 * std::cerr << vEx << std::endl; 00053 * ... 00054 * COH_THROW (vEx); // re-throw managed exception 00055 * } 00056 * catch (const std::exception& e) 00057 * { 00058 * std::cerr << e.what() << std::endl; 00059 * throw; // re-throw standard exception 00060 * } 00061 * @endcode 00062 * 00063 * @see throwable 00064 * 00065 * @author mf 2007.05.05 00066 */ 00067 class COH_EXPORT Exception 00068 : public throwable_spec<Exception, 00069 extends<Object, std::exception>, 00070 implements<>, 00071 Object::View> 00072 { 00073 friend class factory<Exception>; 00074 00075 // ----- constructors --------------------------------------------------- 00076 00077 protected: 00078 /** 00079 * Create a new Exception object 00080 * 00081 * @param vsMsg the message of the exception 00082 * @param veCause the underlying cause of the exception; 00083 * can be <tt>NULL</tt> 00084 * 00085 * @return a Handle to the created Exception 00086 */ 00087 Exception(String::View vsMsg = String::null_string, 00088 Exception::View veCause = NULL); 00089 00090 /** 00091 * Copy constructor 00092 */ 00093 Exception(const Exception&); 00094 00095 00096 // ----- Exception interface -------------------------------------------- 00097 00098 public: 00099 /** 00100 * Return the name of the exception. 00101 */ 00102 virtual String::View getName() const; 00103 00104 /** 00105 * Returns a human-readable description of the Exception. 00106 * 00107 * Note: The String returned is held for the lifetime of this exception 00108 * to guarantee that the result does not go out of scope. This 00109 * method is used by Exception Handles to support the 00110 * std::exception::what() method. 00111 * 00112 * @return the Exception's description 00113 */ 00114 virtual String::View getDescription() const; 00115 00116 /** 00117 * Set the message associated with this exception. 00118 * 00119 * @param vsMsg the message to set for this exception 00120 */ 00121 virtual void setMessage(String::View vsMsg); 00122 00123 /** 00124 * Return the message associated with this exception. 00125 * 00126 * @return the message associated with this exception 00127 */ 00128 virtual String::View getMessage() const; 00129 00130 /** 00131 * Return the underlying cause associated with this exception. 00132 * The underlying cause is the exception that caused this exception 00133 * to be thrown. 00134 * 00135 * @return the underlying cause associated with this exception; 00136 * might be <tt>NULL</tt> 00137 */ 00138 virtual Exception::View getCause() const; 00139 00140 /** 00141 * Set the name of the thread on which this exception was thrown. 00142 * 00143 * @param vsThreadName the thread name 00144 */ 00145 virtual void setThreadName(String::View vsThreadName); 00146 00147 /** 00148 * Return the name of the thread on which the exception was thrown. 00149 * 00150 * @return the name of the thread on which the exception was thrown. 00151 */ 00152 virtual String::View getThreadName() const; 00153 00154 /** 00155 * Set point at which the exception occurred. 00156 * 00157 * @param vaFrames an array of StackTraceElements 00158 */ 00159 virtual void setStackTrace(ObjectArray::View vaFrames); 00160 00161 /** 00162 * Return the stack trace for the exception. 00163 * 00164 * @return an array of StackTraceElements. 00165 */ 00166 virtual ObjectArray::View getStackTrace() const; 00167 00168 /** 00169 * Fills the execution stack trace based on the current threads stack 00170 * and the supplied information about the current stack frame. 00171 * 00172 * @param vsFile the file portion of the first stack frame 00173 * @param nLine the lone portion of the first stack frame 00174 * @param vsFunction the function portion of the first stack frame 00175 */ 00176 virtual Exception::Handle fillInStackTrace( 00177 String::View vsFile = String::null_string, int32_t nLine = 0, 00178 String::View vsFunction = String::null_string); 00179 00180 /** 00181 * Format the stack trace for printing 00182 * 00183 * @return the stack trace 00184 */ 00185 virtual String::View formatStackTrace() const; 00186 00187 /** 00188 * (Re)throw the exception. 00189 * 00190 * The resulting thrown exception may be caught either by it's View 00191 * type, or its alias type. 00192 */ 00193 virtual void raise() const; 00194 00195 00196 // ----- Object interface ----------------------------------------------- 00197 00198 public: 00199 /** 00200 * {@inheritDoc} 00201 */ 00202 virtual TypedHandle<const String> toString() const; 00203 00204 00205 // ----- data members --------------------------------------------------- 00206 00207 protected: 00208 /** 00209 * The message associated with this exception. 00210 */ 00211 FinalView<String> f_vsMessage; 00212 00213 /** 00214 * The stack at the point the exception was thrown 00215 */ 00216 FinalView<ObjectArray> f_vaStackFrames; 00217 00218 /** 00219 * The name of the thread on which the Exception was thrown; 00220 */ 00221 FinalView<String> f_vsThreadName; 00222 00223 /** 00224 * The cause of the exception 00225 */ 00226 FinalView<Exception> f_veCause; 00227 00228 /** 00229 * The detailed human readable description of this exception. 00230 */ 00231 mutable FinalView<String> f_vsDescription; 00232 }; 00233 00234 00235 // ----- helper macros ------------------------------------------------------ 00236 00237 /** 00238 * @hideinitializer 00239 * 00240 * [re]throw a managed exception. If the exception is referenced via a Handle 00241 * it's stack trace will be set to the current stack location, otherwise the 00242 * stack related information will unchanged. 00243 * 00244 * @param E the exception to throw 00245 * 00246 * Usage example: 00247 * @code 00248 * COH_THROW(IOException::create("File Not Found")); 00249 * @endcode 00250 */ 00251 #define COH_THROW(E) COH_NO_RETURN_STMT( \ 00252 coherence::lang::coh_throw((E), __FILE__, __LINE__, COH_CURRENT_FUNCTION)) 00253 00254 /** 00255 * This macro will take the set of streamable contents and convert them to a 00256 * string which will represent the message of the exception being thrown. 00257 * 00258 * @param E the name of the exception that will be thrown 00259 * @param CONTENTS the streamable contents of the message to use when creating 00260 * the exception above. 00261 * 00262 * Note: This Macro only supports Exceptions that have a constructor that takes 00263 * a single message parameter. 00264 * Usage example: 00265 * @code 00266 * COH_THROW_STREAM(IOException, "File: " << hsFile << " not found."); 00267 * @endcode 00268 * @see COH_THROW 00269 */ 00270 #define COH_THROW_STREAM(E, CONTENTS) \ 00271 COH_THROW (E::create(String::View(COH_TO_STRING(CONTENTS)))); 00272 00273 // ----- free functions ----------------------------------------------------- 00274 00275 /** 00276 * This helper method is used by COH_THROW to raise the exception, supplying 00277 * the stack at which it was called. If the exception is referenced via a 00278 * handle the exception's stack will be set prior to being throw. The function 00279 * is marked with compiler specific (no return) statements, so that any calls 00280 * to it will suppress the corresponding compiler warnings. 00281 * 00282 * @param ohE the instance of an exception object to throw 00283 * @param vsFile the current file 00284 * @param nLine the current line 00285 * @param vsFunction the current function 00286 */ 00287 COH_EXPORT COH_NO_RETURN_PRE void coh_throw(Exception::Holder ohE, 00288 String::View vsFile, int32_t nLine, String::View vsFunction) 00289 COH_NO_RETURN_POST; 00290 00291 COH_CLOSE_NAMESPACE2 00292 00293 #endif // COH_EXCEPTION_HPP