| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #pragma once |
| 4 | |
| 5 | #include "Prerequisites/BsPrerequisitesUtil.h" |
| 6 | |
| 7 | namespace bs |
| 8 | { |
| 9 | /** @addtogroup Error |
| 10 | * @{ |
| 11 | */ |
| 12 | |
| 13 | /** |
| 14 | * Base class for all BSF exceptions. |
| 15 | * |
| 16 | * @note BSF doesn't perform exception handling, but these classes remain here in case others wish to enable them. |
| 17 | */ |
| 18 | class Exception : public std::exception |
| 19 | { |
| 20 | public: |
| 21 | Exception(const char* type, const String& description, const String& source) |
| 22 | :mTypeName(type), mDescription(description), mSource(source) |
| 23 | { } |
| 24 | |
| 25 | Exception(const char* type, const String& description, const String& source, const char* file, long line) |
| 26 | : mLine(line), mTypeName(type), mDescription(description), mSource(source), mFile(file) |
| 27 | { } |
| 28 | |
| 29 | Exception(const Exception& rhs) |
| 30 | : mLine(rhs.mLine), mTypeName(rhs.mTypeName), mDescription(rhs.mDescription), |
| 31 | mSource(rhs.mSource), mFile(rhs.mFile) |
| 32 | { } |
| 33 | |
| 34 | ~Exception() noexcept = default; |
| 35 | |
| 36 | void operator = (const Exception& rhs) |
| 37 | { |
| 38 | mDescription = rhs.mDescription; |
| 39 | mSource = rhs.mSource; |
| 40 | mFile = rhs.mFile; |
| 41 | mLine = rhs.mLine; |
| 42 | mTypeName = rhs.mTypeName; |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * Returns a string with the full description of the exception. |
| 47 | * |
| 48 | * @note |
| 49 | * The description contains the error number, the description supplied by the thrower, what routine threw the |
| 50 | * exception, and will also supply extra platform-specific information where applicable. |
| 51 | */ |
| 52 | virtual const String& getFullDescription() const |
| 53 | { |
| 54 | if (mFullDesc.empty()) |
| 55 | { |
| 56 | StringStream desc; |
| 57 | |
| 58 | desc << "bs::framework EXCEPTION(" << mTypeName << "): " |
| 59 | << mDescription |
| 60 | << " in " << mSource; |
| 61 | |
| 62 | if (mLine > 0) |
| 63 | { |
| 64 | desc << " at " << mFile << " (line " << mLine << ")" ; |
| 65 | } |
| 66 | |
| 67 | mFullDesc = desc.str(); |
| 68 | } |
| 69 | |
| 70 | return mFullDesc; |
| 71 | } |
| 72 | |
| 73 | /** Gets the source function that threw the exception. */ |
| 74 | virtual const String& getSource() const { return mSource; } |
| 75 | |
| 76 | /** Gets the source file name in which the exception was thrown. */ |
| 77 | virtual const String& getFile() const { return mFile; } |
| 78 | |
| 79 | /** Gets line number on which the exception was thrown. */ |
| 80 | virtual long getLine() const { return mLine; } |
| 81 | |
| 82 | /** Gets a short description about the exception. */ |
| 83 | virtual const String& getDescription(void) const { return mDescription; } |
| 84 | |
| 85 | /** Overriden std::exception::what. Returns the same value as getFullDescription(). */ |
| 86 | const char* what() const noexcept override { return getFullDescription().c_str(); } |
| 87 | |
| 88 | protected: |
| 89 | long mLine = 0; |
| 90 | String mTypeName; |
| 91 | String mDescription; |
| 92 | String mSource; |
| 93 | String mFile; |
| 94 | mutable String mFullDesc; |
| 95 | }; |
| 96 | |
| 97 | /** Exception for signaling not implemented parts of the code. */ |
| 98 | class NotImplementedException : public Exception |
| 99 | { |
| 100 | public: |
| 101 | NotImplementedException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 102 | : Exception("NotImplementedException" , inDescription, inSource, inFile, inLine) {} |
| 103 | }; |
| 104 | |
| 105 | /** Exception for signaling file system errors when file could not be found. */ |
| 106 | class FileNotFoundException : public Exception |
| 107 | { |
| 108 | public: |
| 109 | FileNotFoundException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 110 | : Exception("FileNotFoundException" , inDescription, inSource, inFile, inLine) {} |
| 111 | }; |
| 112 | |
| 113 | /** Exception for signaling general IO errors. |
| 114 | * |
| 115 | * @note An example being failed to open a file or a network connection. |
| 116 | */ |
| 117 | class IOException : public Exception |
| 118 | { |
| 119 | public: |
| 120 | IOException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 121 | : Exception("IOException" , inDescription, inSource, inFile, inLine) {} |
| 122 | }; |
| 123 | |
| 124 | /** Exception for signaling not currently executing code in not in a valid state. */ |
| 125 | class InvalidStateException : public Exception |
| 126 | { |
| 127 | public: |
| 128 | InvalidStateException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 129 | : Exception("InvalidStateException" , inDescription, inSource, inFile, inLine) {} |
| 130 | }; |
| 131 | |
| 132 | /** Exception for signaling not some parameters you have provided are not valid. */ |
| 133 | class InvalidParametersException : public Exception |
| 134 | { |
| 135 | public: |
| 136 | InvalidParametersException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 137 | : Exception("InvalidParametersException" , inDescription, inSource, inFile, inLine) {} |
| 138 | }; |
| 139 | |
| 140 | /** |
| 141 | * Exception for signaling an internal error, normally something that shouldn't have happened or wasn't anticipated by |
| 142 | * the programmers of that system. |
| 143 | */ |
| 144 | class InternalErrorException : public Exception |
| 145 | { |
| 146 | public: |
| 147 | InternalErrorException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 148 | : Exception("InternalErrorException" , inDescription, inSource, inFile, inLine) {} |
| 149 | }; |
| 150 | |
| 151 | /** Exception for signaling an error in a rendering API. */ |
| 152 | class RenderingAPIException : public Exception |
| 153 | { |
| 154 | public: |
| 155 | RenderingAPIException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 156 | : Exception("RenderingAPIException" , inDescription, inSource, inFile, inLine) {} |
| 157 | }; |
| 158 | |
| 159 | /** Exception for signaling an error in an unit test. */ |
| 160 | class UnitTestException : public Exception |
| 161 | { |
| 162 | public: |
| 163 | UnitTestException(const String& inDescription, const String& inSource, const char* inFile, long inLine) |
| 164 | : Exception("UnitTestException" , inDescription, inSource, inFile, inLine) {} |
| 165 | }; |
| 166 | |
| 167 | /** |
| 168 | * Macro for throwing exceptions that will automatically fill out function name, file name and line number of the |
| 169 | * exception. |
| 170 | */ |
| 171 | // BSF doesn't actually use exceptions, so we just emulate the unhandled exception handler by crashing the application. |
| 172 | #ifndef BS_EXCEPT |
| 173 | #define BS_EXCEPT(type, desc) \ |
| 174 | { \ |
| 175 | static_assert((std::is_base_of<bs::Exception, type>::value), \ |
| 176 | "Invalid exception type (" #type ") for BS_EXCEPT macro." \ |
| 177 | " It needs to derive from bs::Exception."); \ |
| 178 | gCrashHandler().reportCrash(#type, desc, __PRETTY_FUNCTION__, __FILE__, __LINE__); \ |
| 179 | PlatformUtility::terminate(true); \ |
| 180 | } |
| 181 | #endif |
| 182 | |
| 183 | /** @} */ |
| 184 | } |
| 185 | |
| 186 | |