/*
* ORXONOX - the hottest 3D action shooter ever to exist
* > www.orxonox.net <
*
*
* License notice:
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Author:
* Reto Grieder
* Co-authors:
* ...
*
*/
/**
@defgroup ExceptionAssertion Exceptions and assertions
@ingroup Util
*/
/**
@file
@ingroup ExceptionAssertion
@brief
Declaration of facilities to handle exceptions.
@details
Any exception thrown should inherit from orxonox::Exception. There is a macro
\ref CREATE_ORXONOX_EXCEPTION to create a new exception (you can find a list of
available exceptions in the docs of this file).
Throwing exception is also very simple:
@code
ThrowException(General, "Something went wrong");
@endcode
(\c General is a type of exception, see docs of this file)
The exception will automatically contain information about file, line number
and function name it occurred in.
There is also some magic you can do for numbers, etc.:
@code
ThrowException(General, "Error code: " << myInt << ". more info...");
@endcode
It works with an std::ostringstream, so you can feed it all sorts of values.
*/
#ifndef _Exception_H__
#define _Exception_H__
#include "UtilPrereqs.h"
#include
#include
#include
#include "Output.h"
namespace orxonox
{
/** Base class for all exceptions (derived from std::exception).
@details
This class provides support for information about the file, the line
and the function the error occurred.
@see Exception.h
*/
class _UtilExport Exception : public std::exception
{
public:
/**
@brief
Creates the exception but doesn't yet compose the full descrption (because of the virtual functions)
@param description
Exception description as string. This message is supposed to help developers!
@param lineNumber
The number of the code-line in which the exception occurred
@param filename
The file in which the exception occurred
@param functionName
The function in which the exception occurred
*/
Exception(const std::string& description, unsigned int lineNumber,
const char* filename, const char* functionName);
//! Simplified constructor with just a description. If you need more, use the other one.
Exception(const std::string& description);
//! Needed for compatibility with std::exception
virtual ~Exception() throw() { }
//! Returns the error description
const char* what() const throw();
/** Returns a full description with type, line, file and function
@remarks
The composed full description gets stored to fullDescription_. But for compliance
with std::exception, this method has to be const. Hence fullDescription_ is declared
as mutable.
*/
virtual const std::string& getFullDescription() const;
//! Returns the string name of the exception type
virtual std::string getTypeName() const = 0;
//! Returns the short developer written exception
virtual const std::string& getDescription() const { return this->description_; }
//! Returns the line number on which the exception occurred.
virtual unsigned int getLineNumber() const { return this->lineNumber_; }
//! Returns the function in which the exception occurred.
virtual const std::string& getFunctionName() const { return this->functionName_; }
//! Returns the filename in which the exception occurred.
virtual const std::string& getFilename() const { return this->filename_; }
/**
@brief
Retrieves information from an exception caught with "..."
Works for std::exception and CEGUI::Exception
@remarks
Never ever call this function without an exception in the stack!
*/
static std::string handleMessage();
protected:
std::string description_; //!< User typed text about why the exception occurred
unsigned int lineNumber_; //!< Line on which the exception occurred
std::string functionName_; //!< Function (including namespace and class) where the exception occurred
std::string filename_; //!< File where the exception occurred
// mutable because "what()" is a const method
mutable std::string fullDescription_; //!< Full description with line, file and function
};
//! Creates a new type of exception that inherits from orxonox::Exception
#define CREATE_ORXONOX_EXCEPTION(ExceptionName) \
class ExceptionName##Exception : public Exception \
{ \
public: \
ExceptionName##Exception(const std::string& description, \
unsigned int lineNumber, const char* filename, \
const char* functionName) \
: Exception(description, lineNumber, filename, functionName) \
{ } \
\
ExceptionName##Exception(const std::string& description) \
: Exception(description) \
{ } \
\
~ExceptionName##Exception() throw() { } \
\
std::string getTypeName() const { return #ExceptionName; } \
}
// Creates all possible exception types.
// If you want to add a new type, simply copy and adjust a new line here.
CREATE_ORXONOX_EXCEPTION(General);
CREATE_ORXONOX_EXCEPTION(FileNotFound);
CREATE_ORXONOX_EXCEPTION(Argument);
CREATE_ORXONOX_EXCEPTION(PhysicsViolation);
CREATE_ORXONOX_EXCEPTION(ParseError);
CREATE_ORXONOX_EXCEPTION(PluginsNotFound);
CREATE_ORXONOX_EXCEPTION(InitialisationFailed);
CREATE_ORXONOX_EXCEPTION(InitialisationAborted);
CREATE_ORXONOX_EXCEPTION(NotImplemented);
CREATE_ORXONOX_EXCEPTION(GameState);
CREATE_ORXONOX_EXCEPTION(NoGraphics);
CREATE_ORXONOX_EXCEPTION(AbortLoading);
/** Helper function that forwards an exception and displays the message.
@details
This is necessary because only when using 'throw' the objects storage is managed.
*/
template
inline const T& exceptionThrowerHelper(const T& exception)
{
// let the catcher decide whether to display the message also to the user
orxout(internal_error) << exception.getFullDescription() << endl;
return exception;
}
/** Throws an exception and logs a message beforehand.
@param type
Type of the exception as literal (General, Initialisation, etc.)
@param description
Exception description as string
@see Exception.h
*/
#define ThrowException(type, description) \
throw orxonox::exceptionThrowerHelper(type##Exception(static_cast(std::ostringstream().flush() << description).str(), __LINE__, __FILE__, __FUNCTIONNAME__))
} /* namespace orxonox */
#endif /* _Exception_H__ */