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