/*************************************************************************** * Copyright (c) 2002 Jürgen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License (LGPL) * * as published by the Free Software Foundation; either version 2 of * * the License, or (at your option) any later version. * * for detail see the LICENCE text file. * * * * FreeCAD 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 Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with FreeCAD; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * * USA * * * ***************************************************************************/ #ifndef BASE_EXCEPTION_H #define BASE_EXCEPTION_H #include #include #include "BaseClass.h" #include "FileInfo.h" using PyObject = struct _object; /* MACROS FOR THROWING EXCEPTIONS */ /// the macros do NOT mark any message for translation /// If you want to mark text for translation, use the QT_TRANSLATE_NOOP macro /// with the context "Exceptions" and the right throwing macro from below (the one ending in T) /// example: /// THROWMT(Base::ValueError,QT_TRANSLATE_NOOP("Exceptions","The multiplicity cannot be increased /// beyond the degree of the B-Spline.")); /// /// N.B.: The QT_TRANSLATE_NOOP macro won't translate your string. It will just allow lupdate to /// identify that string for translation so that if you ask for a translation (and the translator /// have provided one) at that time it gets translated (e.g. in the UI before showing the message of /// the exception). // NOLINTBEGIN #ifdef _MSC_VER #define THROW(exception) \ { \ exception myexcp; \ myexcp.setDebugInformation(__FILE__, __LINE__, __FUNCSIG__); \ throw myexcp; \ } #define THROWM(exception, message) \ { \ exception myexcp(message); \ myexcp.setDebugInformation(__FILE__, __LINE__, __FUNCSIG__); \ throw myexcp; \ } #define THROWMF_FILEEXCEPTION(message, filenameorfileinfo) \ { \ FileException myexcp(message, filenameorfileinfo); \ myexcp.setDebugInformation(__FILE__, __LINE__, __FUNCSIG__); \ throw myexcp; \ } #define THROWT(exception) \ { \ exception myexcp; \ myexcp.setDebugInformation(__FILE__, __LINE__, __FUNCSIG__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #define THROWMT(exception, message) \ { \ exception myexcp(message); \ myexcp.setDebugInformation(__FILE__, __LINE__, __FUNCSIG__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #define THROWMFT_FILEEXCEPTION(message, filenameorfileinfo) \ { \ FileException myexcp(message, filenameorfileinfo); \ myexcp.setDebugInformation(__FILE__, __LINE__, __FUNCSIG__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #elif defined(__GNUC__) #define THROW(exception) \ { \ exception myexcp; \ myexcp.setDebugInformation(__FILE__, __LINE__, __PRETTY_FUNCTION__); \ throw myexcp; \ } #define THROWM(exception, message) \ { \ exception myexcp(message); \ myexcp.setDebugInformation(__FILE__, __LINE__, __PRETTY_FUNCTION__); \ throw myexcp; \ } #define THROWMF_FILEEXCEPTION(message, filenameorfileinfo) \ { \ FileException myexcp(message, filenameorfileinfo); \ myexcp.setDebugInformation(__FILE__, __LINE__, __PRETTY_FUNCTION__); \ throw myexcp; \ } #define THROWT(exception) \ { \ exception myexcp; \ myexcp.setDebugInformation(__FILE__, __LINE__, __PRETTY_FUNCTION__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #define THROWMT(exception, message) \ { \ exception myexcp(message); \ myexcp.setDebugInformation(__FILE__, __LINE__, __PRETTY_FUNCTION__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #define THROWMFT_FILEEXCEPTION(message, filenameorfileinfo) \ { \ FileException myexcp(message, filenameorfileinfo); \ myexcp.setDebugInformation(__FILE__, __LINE__, __PRETTY_FUNCTION__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #else #define THROW(exception) \ { \ exception myexcp; \ myexcp.setDebugInformation(__FILE__, __LINE__, __func__); \ throw myexcp; \ } #define THROWM(exception, message) \ { \ exception myexcp(message); \ myexcp.setDebugInformation(__FILE__, __LINE__, __func__); \ throw myexcp; \ } #define THROWMF_FILEEXCEPTION(message, filenameorfileinfo) \ { \ FileException myexcp(message, filenameorfileinfo); \ myexcp.setDebugInformation(__FILE__, __LINE__, __func__); \ throw myexcp; \ } #define THROWT(exception) \ { \ exception myexcp; \ myexcp.setDebugInformation(__FILE__, __LINE__, __func__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #define THROWMT(exception, message) \ { \ exception myexcp(message); \ myexcp.setDebugInformation(__FILE__, __LINE__, __func__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #define THROWMFT_FILEEXCEPTION(message, filenameorfileinfo) \ { \ FileException myexcp(message, filenameorfileinfo); \ myexcp.setDebugInformation(__FILE__, __LINE__, __func__); \ myexcp.setTranslatable(true); \ throw myexcp; \ } #endif #define FC_THROWM(_exception, _msg) \ do { \ std::stringstream ss; \ ss << _msg; \ THROWM(_exception, ss.str().c_str()); \ } while (0) // NOLINTEND namespace Base { class BaseExport Exception: public BaseClass { TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: ~Exception() noexcept override = default; Exception& operator=(const Exception& inst); Exception& operator=(Exception&& inst) noexcept; virtual const char* what() const noexcept; /// Reports exception. It includes a mechanism to only report an exception once. virtual void ReportException() const; inline void setMessage(const char* sMessage); inline void setMessage(const std::string& sMessage); // what may differ from the message given by the user in // derived classes inline std::string getMessage() const; inline std::string getFile() const; inline int getLine() const; inline std::string getFunction() const; inline bool getTranslatable() const; inline bool getReported() const { return _isReported; } /// setter methods for including debug information /// intended to use via macro for autofilling of debugging information inline void setDebugInformation(const std::string& file, int line, const std::string& function); inline void setTranslatable(bool translatable); inline void setReported(bool reported) { _isReported = reported; } /// returns a Python dictionary containing the exception data PyObject* getPyObject() override; /// returns sets the exception data from a Python dictionary void setPyObject(PyObject* pydict) override; /// returns the corresponding python exception type virtual PyObject* getPyExceptionType() const; /// Sets the Python error indicator and an error message virtual void setPyException() const; protected: /* sMessage may be: * - a UI compliant string susceptible to being translated and shown to the user in the UI * - a very technical message not intended to be translated or shown to the user in the UI * The preferred way of throwing an exception is using the macros above. * This way, the file, line, and function are automatically inserted. */ explicit Exception(const char* sMessage); explicit Exception(std::string sMessage); Exception(); Exception(const Exception& inst); Exception(Exception&& inst) noexcept; protected: std::string _sErrMsg; std::string _file; int _line; std::string _function; bool _isTranslatable; mutable bool _isReported; }; /** * The AbortException is thrown if a pending operation was aborted. * @author Werner Mayer */ class BaseExport AbortException: public Exception { TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: /// Construction explicit AbortException(const char* sMessage); /// Construction AbortException(); AbortException(const AbortException&) = default; AbortException(AbortException&&) = default; /// Destruction ~AbortException() noexcept override = default; AbortException& operator=(const AbortException&) = default; AbortException& operator=(AbortException&&) = default; /// Description of the exception const char* what() const noexcept override; /// returns the corresponding python exception type PyObject* getPyExceptionType() const override; }; /** * The XMLBaseException can be used to indicate any kind of XML related errors. * @author Werner Mayer */ class BaseExport XMLBaseException: public Exception { public: /// Construction XMLBaseException(); explicit XMLBaseException(const char* sMessage); explicit XMLBaseException(const std::string& sMessage); XMLBaseException(const XMLBaseException&) = default; XMLBaseException(XMLBaseException&&) = default; /// Destruction ~XMLBaseException() noexcept override = default; XMLBaseException& operator=(const XMLBaseException&) = default; XMLBaseException& operator=(XMLBaseException&&) = default; PyObject* getPyExceptionType() const override; }; /** * The XMLParseException is thrown if parsing an XML failed. * @author Werner Mayer */ class BaseExport XMLParseException: public XMLBaseException { public: /// Construction explicit XMLParseException(const char* sMessage); /// Construction explicit XMLParseException(const std::string& sMessage); /// Construction XMLParseException(); XMLParseException(const XMLParseException&) = default; XMLParseException(XMLParseException&&) = default; /// Destruction ~XMLParseException() noexcept override = default; XMLParseException& operator=(const XMLParseException&) = default; XMLParseException& operator=(XMLParseException&&) = default; /// Description of the exception const char* what() const noexcept override; PyObject* getPyExceptionType() const override; }; /** * The XMLAttributeError is thrown if a requested attribute doesn't exist. * @author Werner Mayer */ class BaseExport XMLAttributeError: public XMLBaseException { public: /// Construction explicit XMLAttributeError(const char* sMessage); /// Construction explicit XMLAttributeError(const std::string& sMessage); /// Construction XMLAttributeError(); XMLAttributeError(const XMLAttributeError&) = default; XMLAttributeError(XMLAttributeError&&) = default; /// Destruction ~XMLAttributeError() noexcept override = default; XMLAttributeError& operator=(const XMLAttributeError&) = default; XMLAttributeError& operator=(XMLAttributeError&&) = default; /// Description of the exception const char* what() const noexcept override; PyObject* getPyExceptionType() const override; }; /** File exception handling class * This class is specialized to go with exception thrown in case of File IO Problems. * @author Juergen Riegel */ class BaseExport FileException: public Exception { public: /// With massage and file name explicit FileException(const char* sMessage, const char* sFileName = nullptr); /// With massage and file name FileException(const char* sMessage, const FileInfo& File); /// standard construction FileException(); FileException(const FileException&) = default; FileException(FileException&&) = default; /// Destruction ~FileException() noexcept override = default; /// Assignment operator FileException& operator=(const FileException&) = default; FileException& operator=(FileException&&) = default; /// Description of the exception const char* what() const noexcept override; /// Report generation void ReportException() const override; /// Get file name for use with translatable message std::string getFileName() const; /// returns a Python dictionary containing the exception data PyObject* getPyObject() override; /// returns sets the exception data from a Python dictionary void setPyObject(PyObject* pydict) override; PyObject* getPyExceptionType() const override; protected: FileInfo file; // necessary for what() legacy behaviour as it returns a buffer that // can not be of a temporary object to be destroyed at end of what() std::string _sErrMsgAndFileName; void setFileName(const char* sFileName = nullptr); }; /** * The FileSystemError can be used to indicate errors on file system * e.g. if renaming of a file failed. * @author Werner Mayer */ class BaseExport FileSystemError: public Exception { public: /// Construction FileSystemError(); explicit FileSystemError(const char* sMessage); explicit FileSystemError(const std::string& sMessage); FileSystemError(const FileSystemError&) = default; FileSystemError(FileSystemError&&) = default; /// Destruction ~FileSystemError() noexcept override = default; FileSystemError& operator=(const FileSystemError&) = default; FileSystemError& operator=(FileSystemError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The BadFormatError can be used to indicate errors in a data structure. * @author Werner Mayer */ class BaseExport BadFormatError: public Exception { public: /// Construction BadFormatError(); explicit BadFormatError(const char* sMessage); explicit BadFormatError(const std::string& sMessage); BadFormatError(const BadFormatError&) = default; BadFormatError(BadFormatError&&) = default; /// Destruction ~BadFormatError() noexcept override = default; BadFormatError& operator=(const BadFormatError&) = default; BadFormatError& operator=(BadFormatError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The MemoryException is thrown if not enough memory can be allocated. * @author Werner Mayer */ #if defined(__GNUC__) // It seems that the calling instance of our new handler expects a bad_alloc exception class BaseExport MemoryException: public Exception, virtual public std::bad_alloc #else class BaseExport MemoryException: public Exception #endif { public: /// Construction MemoryException(); /// Construction MemoryException(const MemoryException& inst); MemoryException(MemoryException&& inst) noexcept; /// Destruction ~MemoryException() noexcept override = default; /// Assignment operator MemoryException& operator=(const MemoryException& inst); MemoryException& operator=(MemoryException&& inst) noexcept; #if defined(__GNUC__) /// Description of the exception const char* what() const noexcept override; #endif PyObject* getPyExceptionType() const override; }; /** * The AccessViolation can be used in an own signal handler. * @author Werner Mayer */ class BaseExport AccessViolation: public Exception { public: /// Construction AccessViolation(); explicit AccessViolation(const char* sMessage); explicit AccessViolation(const std::string& sMessage); AccessViolation(const AccessViolation&) = default; AccessViolation(AccessViolation&&) = default; /// Destruction ~AccessViolation() noexcept override = default; AccessViolation& operator=(const AccessViolation&) = default; AccessViolation& operator=(AccessViolation&&) = default; PyObject* getPyExceptionType() const override; }; /** * The AbnormalProgramTermination can be used in an own signal handler. * @author Werner Mayer */ class BaseExport AbnormalProgramTermination: public Exception { public: /// Construction AbnormalProgramTermination(); /// Construction explicit AbnormalProgramTermination(const char* sMessage); explicit AbnormalProgramTermination(const std::string& sMessage); AbnormalProgramTermination(const AbnormalProgramTermination&) = default; AbnormalProgramTermination(AbnormalProgramTermination&&) = default; /// Destruction ~AbnormalProgramTermination() noexcept override = default; AbnormalProgramTermination& operator=(const AbnormalProgramTermination&) = default; AbnormalProgramTermination& operator=(AbnormalProgramTermination&&) = default; PyObject* getPyExceptionType() const override; }; /** * The UnknownProgramOption can be used to indicate an unknown program option. * @author Werner Mayer */ class BaseExport UnknownProgramOption: public Exception { public: /// Construction UnknownProgramOption(); explicit UnknownProgramOption(const char* sMessage); explicit UnknownProgramOption(const std::string& sMessage); UnknownProgramOption(const UnknownProgramOption&) = default; UnknownProgramOption(UnknownProgramOption&&) = default; /// Destruction ~UnknownProgramOption() noexcept override = default; UnknownProgramOption& operator=(const UnknownProgramOption&) = default; UnknownProgramOption& operator=(UnknownProgramOption&&) = default; PyObject* getPyExceptionType() const override; }; /** * The ProgramInformation can be used to show information about the program. * @author Werner Mayer */ class BaseExport ProgramInformation: public Exception { public: /// Construction ProgramInformation(); explicit ProgramInformation(const char* sMessage); explicit ProgramInformation(const std::string& sMessage); ProgramInformation(const ProgramInformation&) = default; ProgramInformation(ProgramInformation&&) = default; /// Destruction ~ProgramInformation() noexcept override = default; ProgramInformation& operator=(const ProgramInformation&) = default; ProgramInformation& operator=(ProgramInformation&&) = default; }; /** * The TypeError can be used to indicate the usage of a wrong type. * @author Werner Mayer */ class BaseExport TypeError: public Exception { public: /// Construction TypeError(); explicit TypeError(const char* sMessage); explicit TypeError(const std::string& sMessage); TypeError(const TypeError&) = default; TypeError(TypeError&&) = default; /// Destruction ~TypeError() noexcept override = default; TypeError& operator=(const TypeError&) = default; TypeError& operator=(TypeError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The ValueError can be used to indicate the usage of a wrong value. * @author Werner Mayer */ class BaseExport ValueError: public Exception { public: /// Construction ValueError(); explicit ValueError(const char* sMessage); explicit ValueError(const std::string& sMessage); ValueError(const ValueError&) = default; ValueError(ValueError&&) = default; /// Destruction ~ValueError() noexcept override = default; ValueError& operator=(const ValueError&) = default; ValueError& operator=(ValueError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The IndexError can be used when a sequence subscript is out of range. * @author Werner Mayer */ class BaseExport IndexError: public Exception { public: /// Construction IndexError(); explicit IndexError(const char* sMessage); explicit IndexError(const std::string& sMessage); IndexError(const IndexError&) = default; IndexError(IndexError&&) = default; /// Destruction ~IndexError() noexcept override = default; IndexError& operator=(const IndexError&) = default; IndexError& operator=(IndexError&&) = default; PyObject* getPyExceptionType() const override; }; class BaseExport NameError: public Exception { public: /// Construction NameError(); explicit NameError(const char* sMessage); explicit NameError(const std::string& sMessage); NameError(const NameError&) = default; NameError(NameError&&) = default; /// Destruction ~NameError() noexcept override = default; NameError& operator=(const NameError&) = default; NameError& operator=(NameError&&) = default; PyObject* getPyExceptionType() const override; }; class BaseExport ImportError: public Exception { public: /// Construction ImportError(); explicit ImportError(const char* sMessage); explicit ImportError(const std::string& sMessage); ImportError(const ImportError&) = default; ImportError(ImportError&&) = default; /// Destruction ~ImportError() noexcept override = default; ImportError& operator=(const ImportError&) = default; ImportError& operator=(ImportError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The AttributeError can be used to indicate the usage of a wrong value. * @author Werner Mayer */ class BaseExport AttributeError: public Exception { public: /// Construction AttributeError(); explicit AttributeError(const char* sMessage); explicit AttributeError(const std::string& sMessage); AttributeError(const AttributeError&) = default; AttributeError(AttributeError&&) = default; /// Destruction ~AttributeError() noexcept override = default; AttributeError& operator=(const AttributeError&) = default; AttributeError& operator=(AttributeError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The PropertyError can be used to indicate the usage of a wrong property name or value. * @author Mario Passaglia */ class BaseExport PropertyError: public AttributeError { public: /// Construction PropertyError(); explicit PropertyError(const char* sMessage); explicit PropertyError(const std::string& sMessage); PropertyError(const PropertyError&) = default; PropertyError(PropertyError&&) = default; /// Destruction ~PropertyError() noexcept override = default; PropertyError& operator=(const PropertyError&) = default; PropertyError& operator=(PropertyError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The RuntimeError can be used to indicate an unknown exception at runtime. * @author Werner Mayer */ class BaseExport RuntimeError: public Exception { public: /// Construction RuntimeError(); explicit RuntimeError(const char* sMessage); explicit RuntimeError(const std::string& sMessage); RuntimeError(const RuntimeError&) = default; RuntimeError(RuntimeError&&) = default; /// Destruction ~RuntimeError() noexcept override = default; RuntimeError& operator=(const RuntimeError&) = default; RuntimeError& operator=(RuntimeError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The BadGraphError can be used to indicate that a graph is e.g. not a DAG. * @author Werner Mayer */ class BaseExport BadGraphError: public RuntimeError { public: /// Construction BadGraphError(); explicit BadGraphError(const char* sMessage); explicit BadGraphError(const std::string& sMessage); BadGraphError(const BadGraphError&) = default; BadGraphError(BadGraphError&&) = default; /// Destruction ~BadGraphError() noexcept override = default; BadGraphError& operator=(const BadGraphError&) = default; BadGraphError& operator=(BadGraphError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The NotImplementedError can be used to indicate that an invoked function is not implemented. * @author Werner Mayer */ class BaseExport NotImplementedError: public Exception { public: /// Construction NotImplementedError(); explicit NotImplementedError(const char* sMessage); explicit NotImplementedError(const std::string& sMessage); NotImplementedError(const NotImplementedError&) = default; NotImplementedError(NotImplementedError&&) = default; /// Destruction ~NotImplementedError() noexcept override = default; NotImplementedError& operator=(const NotImplementedError&) = default; NotImplementedError& operator=(NotImplementedError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The ZeroDivisionError can be used to indicate a division by zero. * @author Werner Mayer */ class BaseExport ZeroDivisionError: public Exception { public: /// Construction ZeroDivisionError(); explicit ZeroDivisionError(const char* sMessage); explicit ZeroDivisionError(const std::string& sMessage); ZeroDivisionError(const ZeroDivisionError&) = default; ZeroDivisionError(ZeroDivisionError&&) = default; /// Destruction ~ZeroDivisionError() noexcept override = default; ZeroDivisionError& operator=(const ZeroDivisionError&) = default; ZeroDivisionError& operator=(ZeroDivisionError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The ReferenceError can be used to indicate a reference counter has the wrong value. * @author Werner Mayer */ class BaseExport ReferenceError: public Exception { public: /// Construction ReferenceError(); explicit ReferenceError(const char* sMessage); explicit ReferenceError(const std::string& sMessage); ReferenceError(const ReferenceError&) = default; ReferenceError(ReferenceError&&) = default; /// Destruction ~ReferenceError() noexcept override = default; ReferenceError& operator=(const ReferenceError&) = default; ReferenceError& operator=(ReferenceError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The ExpressionError can be used to indicate erroneous.input * to the expression engine. * @author Werner Mayer */ class BaseExport ExpressionError: public Exception { public: /// Construction ExpressionError(); explicit ExpressionError(const char* sMessage); explicit ExpressionError(const std::string& sMessage); ExpressionError(const ExpressionError&) = default; ExpressionError(ExpressionError&&) = default; /// Destruction ~ExpressionError() noexcept override = default; ExpressionError& operator=(const ExpressionError&) = default; ExpressionError& operator=(ExpressionError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The ParserError can be used to indicate the parsing error. * @author Werner Mayer */ class BaseExport ParserError: public Exception { public: /// Construction ParserError(); explicit ParserError(const char* sMessage); explicit ParserError(const std::string& sMessage); ParserError(const ParserError&) = default; ParserError(ParserError&&) = default; /// Destruction ~ParserError() noexcept override = default; ParserError& operator=(const ParserError&) = default; ParserError& operator=(ParserError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The UnicodeError can be used to indicate unicode encoding/decoding error. * @author Werner Mayer */ class BaseExport UnicodeError: public Exception { public: /// Construction UnicodeError(); explicit UnicodeError(const char* sMessage); explicit UnicodeError(const std::string& sMessage); UnicodeError(const UnicodeError&) = default; UnicodeError(UnicodeError&&) = default; /// Destruction ~UnicodeError() noexcept override = default; UnicodeError& operator=(const UnicodeError&) = default; UnicodeError& operator=(UnicodeError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The OverflowError can be used to indicate overflows of numbers. * @author Werner Mayer */ class BaseExport OverflowError: public Exception { public: /// Construction OverflowError(); explicit OverflowError(const char* sMessage); explicit OverflowError(const std::string& sMessage); OverflowError(const OverflowError&) = default; OverflowError(OverflowError&&) = default; /// Destruction ~OverflowError() noexcept override = default; OverflowError& operator=(const OverflowError&) = default; OverflowError& operator=(OverflowError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The UnderflowError can be used to indicate underflows of numbers. * @author Werner Mayer */ class BaseExport UnderflowError: public Exception { public: /// Construction UnderflowError(); explicit UnderflowError(const char* sMessage); explicit UnderflowError(const std::string& sMessage); UnderflowError(const UnderflowError&) = default; UnderflowError(UnderflowError&&) = default; /// Destruction ~UnderflowError() noexcept override = default; UnderflowError& operator=(const UnderflowError&) = default; UnderflowError& operator=(UnderflowError&&) = default; PyObject* getPyExceptionType() const override; }; /** * The UnitsMismatchError can be used to indicate that quantities with different units are used. * @author Werner Mayer */ class BaseExport UnitsMismatchError: public Exception { public: /// Construction UnitsMismatchError(); explicit UnitsMismatchError(const char* sMessage); explicit UnitsMismatchError(const std::string& sMessage); UnitsMismatchError(const UnitsMismatchError&) = default; UnitsMismatchError(UnitsMismatchError&&) = default; /// Destruction ~UnitsMismatchError() noexcept override = default; UnitsMismatchError& operator=(const UnitsMismatchError&) = default; UnitsMismatchError& operator=(UnitsMismatchError&&) = default; PyObject* getPyExceptionType() const override; }; /* The CADKernelError can be used to indicate an exception originating in the CAD Kernel * allowing to propagate the error messages of, for example, OCC Standard_Failure exception to * the FreeCAD application without making the FreeCAD application depend on OCC. * @author Abdullah Tahiri */ class BaseExport CADKernelError: public Exception { public: /// Construction CADKernelError(); explicit CADKernelError(const char* sMessage); explicit CADKernelError(const std::string& sMessage); CADKernelError(const CADKernelError&) = default; CADKernelError(CADKernelError&&) = default; /// Destruction ~CADKernelError() noexcept override = default; CADKernelError& operator=(const CADKernelError&) = default; CADKernelError& operator=(CADKernelError&&) = default; PyObject* getPyExceptionType() const override; }; /* The RestoreError can be used to try to do a best recovery effort when an error during restoring * occurs. The best recovery effort may be to ignore the element altogether or to insert a * placeholder depending on where the actual element being restored is used. * * For example, if it is part of an array (e.g. PropertyList) and the order in the array is * relevant, it is better to have a placeholder than to fail to restore the whole array. */ class BaseExport RestoreError: public Exception { public: /// Construction RestoreError(); explicit RestoreError(const char* sMessage); explicit RestoreError(const std::string& sMessage); RestoreError(const RestoreError&) = default; RestoreError(RestoreError&&) = default; /// Destruction ~RestoreError() noexcept override = default; RestoreError& operator=(const RestoreError&) = default; RestoreError& operator=(RestoreError&&) = default; PyObject* getPyExceptionType() const override; }; inline void Exception::setMessage(const char* sMessage) { _sErrMsg = sMessage; } inline void Exception::setMessage(const std::string& sMessage) { _sErrMsg = sMessage; } inline std::string Exception::getMessage() const { return _sErrMsg; } inline std::string Exception::getFile() const { return _file; } inline int Exception::getLine() const { return _line; } inline std::string Exception::getFunction() const { return _function; } inline bool Exception::getTranslatable() const { return _isTranslatable; } inline void Exception::setDebugInformation(const std::string& file, int line, const std::string& function) { _file = file; _line = line; _function = function; } inline void Exception::setTranslatable(bool translatable) { _isTranslatable = translatable; } #if defined(__GNUC__) && defined(FC_OS_LINUX) class SignalException { public: SignalException(); ~SignalException(); private: static void throw_signal(int signum); private: // clang-format off struct sigaction new_action {}, old_action {}; bool ok {false}; // clang-format on }; #endif } // namespace Base #endif // BASE_EXCEPTION_H