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