Coverage Report

Created: 2025-11-11 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ogre/OgreMain/include/OgreException.h
Line
Count
Source
1
/*
2
-----------------------------------------------------------------------------
3
This source file is part of OGRE
4
(Object-oriented Graphics Rendering Engine)
5
For the latest info, see http://www.ogre3d.org/
6
7
Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9
Permission is hereby granted, free of charge, to any person obtaining a copy
10
of this software and associated documentation files (the "Software"), to deal
11
in the Software without restriction, including without limitation the rights
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
copies of the Software, and to permit persons to whom the Software is
14
furnished to do so, subject to the following conditions:
15
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
18
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
THE SOFTWARE.
26
-----------------------------------------------------------------------------
27
*/
28
#ifndef __Exception_H_
29
#define __Exception_H_
30
31
// Precompiler options
32
#include "OgrePrerequisites.h"
33
#include "OgreString.h"
34
#include <exception>
35
#include "OgreHeaderPrefix.h"
36
37
// Check for OGRE assert mode
38
39
// RELEASE_EXCEPTIONS mode
40
#if OGRE_ASSERT_MODE == 1
41
#   if OGRE_DEBUG_MODE
42
#       define OgreAssert( a, b ) assert( (a) && (b) )
43
#   else
44
#       define OgreAssert( a, b ) if( !(a) ) OGRE_EXCEPT_2( Ogre::Exception::ERR_RT_ASSERTION_FAILED, (#a " failed. " b) )
45
#   endif
46
47
// EXCEPTIONS mode
48
#elif OGRE_ASSERT_MODE == 2
49
#   define OgreAssert( a, b ) if( !(a) ) OGRE_EXCEPT_2( Ogre::Exception::ERR_RT_ASSERTION_FAILED, (#a " failed. " b) )
50
// STANDARD mode
51
#else
52
/** Checks a condition at runtime and throws exception/ aborts if it fails.
53
 *
54
 * The macros OgreAssert (and OgreAssertDbg) evaluate the specified expression.
55
 * If it is 0, OgreAssert raises an error (see Ogre::RuntimeAssertionException) in Release configuration
56
 * and aborts in Debug configuration.
57
 * The macro OgreAssert checks the condition in both Debug and Release configurations
58
 * while OgreAssertDbg is only retained in the Debug configuration.
59
 *
60
 * To always abort instead of throwing an exception or disabling OgreAssert in Release configuration altogether,
61
 * set OGRE_ASSERT_MODE in CMake accordingly.
62
 */
63
#   define OgreAssert( expr, mesg ) assert( (expr) && (mesg) )
64
#endif
65
66
#if OGRE_DEBUG_MODE
67
#   define OgreAssertDbg( a, b ) OgreAssert( a, b )
68
#else
69
/// replaced with OgreAssert(expr, mesg) in Debug configuration
70
#   define OgreAssertDbg( expr, mesg )
71
#endif
72
73
namespace Ogre {
74
75
    /** \addtogroup Core
76
    *  @{
77
    */
78
    /** \addtogroup General
79
    *  @{
80
    */
81
    /** When thrown, provides information about an error that has occurred inside the engine.
82
83
        OGRE never uses return values to indicate errors. Instead, if an
84
        error occurs, an exception is thrown, and this is the object that
85
        encapsulates the detail of the problem. The application using
86
        OGRE should always ensure that the exceptions are caught, so all
87
        OGRE engine functions should occur within a
88
        try{} catch(Ogre::Exception& e) {} block.
89
        @par
90
            The user application should never create any instances of this
91
            object unless it wishes to unify its error handling using the
92
            same object.
93
    */
94
    class _OgreExport Exception : public std::exception
95
    {
96
    protected:
97
        long line;
98
        const char* typeName;
99
        String description;
100
        String source;
101
        const char* file;
102
        String fullDesc; // storage for char* returned by what()
103
    public:
104
        /** Static definitions of error codes.
105
            @todo
106
                Add many more exception codes, since we want the user to be able
107
                to catch most of them.
108
        */
109
        enum ExceptionCodes {
110
            ERR_CANNOT_WRITE_TO_FILE,
111
            ERR_INVALID_STATE,
112
            ERR_INVALIDPARAMS,
113
            ERR_RENDERINGAPI_ERROR,
114
            ERR_DUPLICATE_ITEM,
115
            ERR_ITEM_NOT_FOUND = ERR_DUPLICATE_ITEM,
116
            ERR_FILE_NOT_FOUND,
117
            ERR_INTERNAL_ERROR,
118
            ERR_RT_ASSERTION_FAILED,
119
            ERR_NOT_IMPLEMENTED,
120
            ERR_INVALID_CALL
121
        };
122
123
        /** Default constructor.
124
        */
125
        Exception( int number, const String& description, const String& source );
126
127
        /** Advanced constructor.
128
        */
129
        Exception( int number, const String& description, const String& source, const char* type, const char* file, long line );
130
131
        /** Copy constructor.
132
        */
133
        Exception(const Exception& rhs);
134
135
        /// Needed for compatibility with std::exception
136
512
        ~Exception() throw() {}
137
138
        /** Returns a string with the full description of this error.
139
140
            The description contains the error number, the description
141
            supplied by the thrower, what routine threw the exception,
142
            and will also supply extra platform-specific information
143
            where applicable. For example - in the case of a rendering
144
            library error, the description of the error will include both
145
            the place in which OGRE found the problem, and a text
146
            description from the 3D rendering library, if available.
147
        */
148
0
        const String& getFullDescription(void) const { return fullDesc; }
149
150
        /** Gets the source function.
151
        */
152
0
        const String &getSource() const { return source; }
153
154
        /** Gets source file name.
155
        */
156
0
        const char* getFile() const { return file; }
157
158
        /** Gets line number.
159
        */
160
0
        long getLine() const { return line; }
161
162
        /** Returns a string with only the 'description' field of this exception. Use 
163
            getFullDescriptionto get a full description of the error including line number,
164
            error number and what function threw the exception.
165
        */
166
0
        const String &getDescription(void) const { return description; }
167
168
0
        const char* what() const throw() override { return fullDesc.c_str(); }
169
        
170
    };
171
172
173
    /** Template struct which creates a distinct type for each exception code.
174
    @note
175
    This is useful because it allows us to create an overloaded method
176
    for returning different exception types by value without ambiguity. 
177
    From 'Modern C++ Design' (Alexandrescu 2001).
178
    */
179
    class _OgreExport UnimplementedException : public Exception 
180
    {
181
    public:
182
        UnimplementedException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
183
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
184
    };
185
    class _OgreExport FileNotFoundException : public Exception
186
    {
187
    public:
188
        FileNotFoundException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
189
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
190
    };
191
    class _OgreExport IOException : public Exception
192
    {
193
    public:
194
        IOException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
195
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
196
    };
197
    class _OgreExport InvalidStateException : public Exception
198
    {
199
    public:
200
        InvalidStateException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
201
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
202
    };
203
    class _OgreExport InvalidParametersException : public Exception
204
    {
205
    public:
206
        InvalidParametersException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
207
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
208
    };
209
    class _OgreExport ItemIdentityException : public Exception
210
    {
211
    public:
212
        ItemIdentityException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
213
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
214
    };
215
    class _OgreExport InternalErrorException : public Exception
216
    {
217
    public:
218
        InternalErrorException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
219
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
220
    };
221
    class _OgreExport RenderingAPIException : public Exception
222
    {
223
    public:
224
        RenderingAPIException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
225
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
226
    };
227
    class _OgreExport RuntimeAssertionException : public Exception
228
    {
229
    public:
230
        RuntimeAssertionException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
231
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
232
    };
233
    class _OgreExport InvalidCallException : public Exception
234
    {
235
    public:
236
        InvalidCallException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine)
237
0
            : Exception(inNumber, inDescription, inSource, __FUNCTION__, inFile, inLine) {}
238
    };
239
240
    /** Class implementing dispatch methods in order to construct by-value
241
        exceptions of a derived type based just on an exception code.
242
243
        This nicely handles construction of derived Exceptions by value (needed
244
        for throwing) without suffering from ambiguity - each code is turned into
245
        a distinct type so that methods can be overloaded. This allows OGRE_EXCEPT
246
        to stay small in implementation (desirable since it is embedded) whilst
247
        still performing rich code-to-type mapping. 
248
    */
249
    class ExceptionFactory
250
    {
251
    private:
252
        /// Private constructor, no construction
253
0
        ExceptionFactory() {}
254
        static OGRE_NORETURN void _throwException(
255
            Exception::ExceptionCodes code, int number,
256
            const String& desc, 
257
            const String& src, const char* file, long line)
258
0
        {
259
0
            switch (code)
260
0
            {
261
0
            case Exception::ERR_CANNOT_WRITE_TO_FILE:   throw IOException(number, desc, src, file, line);
262
0
            case Exception::ERR_INVALID_STATE:          throw InvalidStateException(number, desc, src, file, line);
263
0
            case Exception::ERR_INVALIDPARAMS:          throw InvalidParametersException(number, desc, src, file, line);
264
0
            case Exception::ERR_RENDERINGAPI_ERROR:     throw RenderingAPIException(number, desc, src, file, line);
265
0
            case Exception::ERR_DUPLICATE_ITEM:         throw ItemIdentityException(number, desc, src, file, line);
266
0
            case Exception::ERR_FILE_NOT_FOUND:         throw FileNotFoundException(number, desc, src, file, line);
267
0
            case Exception::ERR_INTERNAL_ERROR:         throw InternalErrorException(number, desc, src, file, line);
268
0
            case Exception::ERR_RT_ASSERTION_FAILED:    throw RuntimeAssertionException(number, desc, src, file, line);
269
0
            case Exception::ERR_NOT_IMPLEMENTED:        throw UnimplementedException(number, desc, src, file, line);
270
0
            case Exception::ERR_INVALID_CALL:           throw InvalidCallException(number, desc, src, file, line);
271
0
            default:                                    throw Exception(number, desc, src, "Exception", file, line);
272
0
            }
273
0
        }
274
    public:
275
        static OGRE_NORETURN void throwException(
276
            Exception::ExceptionCodes code,
277
            const String& desc,
278
            const String& src, const char* file, long line)
279
0
        {
280
0
            _throwException(code, code, desc, src, file, line);
281
0
        }
282
    };
283
    
284
285
    
286
#ifndef OGRE_EXCEPT
287
#define OGRE_EXCEPT_3(code, desc, src)  Ogre::ExceptionFactory::throwException(code, desc, src, __FILE__, __LINE__)
288
#define OGRE_EXCEPT_2(code, desc)       Ogre::ExceptionFactory::throwException(code, desc, __FUNCTION__, __FILE__, __LINE__)
289
#define OGRE_EXCEPT_CHOOSER(arg1, arg2, arg3, arg4, ...) arg4
290
#define OGRE_EXPAND(x) x // MSVC workaround
291
#define OGRE_EXCEPT(...) OGRE_EXPAND(OGRE_EXCEPT_CHOOSER(__VA_ARGS__, OGRE_EXCEPT_3, OGRE_EXCEPT_2)(__VA_ARGS__))
292
#endif
293
    /** @} */
294
    /** @} */
295
296
} // Namespace Ogre
297
298
#include "OgreHeaderSuffix.h"
299
300
#endif