| 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 |  | 
|---|