| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #ifndef BASE_EXCEPTION_H
|
| | #define BASE_EXCEPTION_H
|
| |
|
| | #include <FCConfig.h>
|
| |
|
| | #include <csignal>
|
| | #include <source_location>
|
| | #include <string>
|
| |
|
| | #include "BaseClass.h"
|
| | #include "FileInfo.h"
|
| |
|
| | using PyObject = struct _object;
|
| |
|
| |
|
| | #if defined(__cpp_lib_source_location)
|
| | # define HAVE_STD_SOURCE_LOCATION 1
|
| | #else
|
| | # undef HAVE_STD_SOURCE_LOCATION
|
| | #endif
|
| |
|
| | #if defined(__clang__) && __clang_major__ <= 15
|
| | # undef HAVE_STD_SOURCE_LOCATION
|
| | #endif
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | #if defined(HAVE_STD_SOURCE_LOCATION)
|
| |
|
| | # define THROWM(exc, msg) Base::setupAndThrowException<exc>((msg), std::source_location::current());
|
| | # define THROWMT(exc, msg) \
|
| | Base::setupAndThrowException<exc>((msg), std::source_location::current(), true);
|
| | # define FC_THROWM(exception, msg) \
|
| | do { \
|
| | std::stringstream ss; \
|
| | ss << msg; \
|
| | THROWM(exception, ss.str()); \
|
| | } while (0)
|
| |
|
| |
|
| | namespace Base
|
| | {
|
| | template<typename ExceptionType>
|
| | [[noreturn]] void setupAndThrowException(
|
| | const std::string message,
|
| | const std::source_location location,
|
| | const bool translatable = false
|
| | )
|
| | {
|
| | ExceptionType exception {message};
|
| | exception.setTranslatable(translatable);
|
| | exception.setDebugInformation(location);
|
| | throw exception;
|
| | }
|
| | }
|
| |
|
| | #else
|
| |
|
| | # ifdef _MSC_VER
|
| | # define FC_THROW_INFO __FILE__, __LINE__, __FUNCSIG__
|
| | # elif __GNUC__
|
| | # define FC_THROW_INFO __FILE__, __LINE__, __PRETTY_FUNCTION__
|
| | # else
|
| | # define FC_THROW_INFO __FILE__, __LINE__, __func__
|
| | # endif
|
| |
|
| | # define THROWM(exc, msg) Base::setupAndThrowException<exc>(msg, FC_THROW_INFO);
|
| | # define THROWMT(exc, msg) Base::setupAndThrowException<exc>(msg, FC_THROW_INFO, true);
|
| | # define FC_THROWM(exception, msg) \
|
| | do { \
|
| | std::stringstream ss; \
|
| | ss << msg; \
|
| | THROWM(exception, ss.str()); \
|
| | } while (0)
|
| | namespace Base
|
| | {
|
| | template<typename ExceptionType>
|
| | [[noreturn]] void setupAndThrowException(
|
| | const std::string message,
|
| | const char* file,
|
| | const int line,
|
| | const char* func,
|
| | const bool translatable = false
|
| | )
|
| | {
|
| | ExceptionType exception {message};
|
| | exception.setTranslatable(translatable);
|
| | exception.setDebugInformation(file, line, func);
|
| | throw exception;
|
| | }
|
| | }
|
| |
|
| | #endif
|
| |
|
| |
|
| |
|
| | template<typename Exception>
|
| | constexpr void THROWM_(
|
| | const std::string& msg,
|
| | const std::source_location location = std::source_location::current()
|
| | )
|
| | {
|
| | Base::setupAndThrowException<Exception>(msg, location);
|
| | }
|
| |
|
| | template<typename Exception>
|
| | constexpr void THROWMT_(
|
| | const std::string& msg,
|
| | const std::source_location location = std::source_location::current()
|
| | )
|
| | {
|
| | Base::setupAndThrowException<Exception>(msg, location, true);
|
| | }
|
| |
|
| | template<typename Exception>
|
| | constexpr void FC_THROWM_(
|
| | const std::string& raw_msg,
|
| | const std::source_location location = std::source_location::current()
|
| | )
|
| | {
|
| | THROWM_<Exception>(raw_msg, location);
|
| | }
|
| |
|
| | namespace Base
|
| | {
|
| |
|
| | class BaseExport Exception: public BaseClass
|
| | {
|
| | TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
| |
|
| | public:
|
| | explicit Exception(std::string message = "FreeCAD Exception");
|
| | ~Exception() noexcept override = default;
|
| |
|
| | Exception& operator=(const Exception& inst);
|
| | Exception& operator=(Exception&& inst) noexcept;
|
| |
|
| | virtual const char* what() const noexcept;
|
| | virtual void reportException() const;
|
| |
|
| | inline void setMessage(const std::string& message);
|
| |
|
| |
|
| | 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;
|
| | inline void setReported(bool reported) const;
|
| |
|
| | #if defined(HAVE_STD_SOURCE_LOCATION)
|
| | inline void setDebugInformation(const std::source_location& location);
|
| | #else
|
| | inline void setDebugInformation(const char* file, int line, const char* func);
|
| | #endif
|
| |
|
| | inline void setTranslatable(bool translatable);
|
| |
|
| | PyObject* getPyObject() override;
|
| | void setPyObject(PyObject* pydict) override;
|
| |
|
| | virtual PyObject* getPyExceptionType() const;
|
| | virtual void setPyException() const;
|
| |
|
| | protected:
|
| | Exception(const Exception& inst);
|
| | Exception(Exception&& inst) noexcept;
|
| |
|
| | private:
|
| | std::string errorMessage;
|
| | std::string fileName;
|
| | int lineNum {0};
|
| | std::string functionName;
|
| | bool isTranslatable {false};
|
| | mutable bool hasBeenReported {false};
|
| | };
|
| |
|
| | class BaseExport AbortException: public Exception
|
| | {
|
| | TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
| |
|
| | public:
|
| | explicit AbortException(const std::string& message = "Aborted operation");
|
| |
|
| | const char* what() const noexcept override;
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport XMLBaseException: public Exception
|
| | {
|
| | public:
|
| | explicit XMLBaseException(const std::string& message = "XML base exception");
|
| |
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport XMLParseException: public XMLBaseException
|
| | {
|
| | public:
|
| | explicit XMLParseException(const std::string& message = "XML parse exception");
|
| |
|
| | const char* what() const noexcept override;
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport XMLAttributeError: public XMLBaseException
|
| | {
|
| | public:
|
| | explicit XMLAttributeError(const std::string& message = "XML attribute error");
|
| |
|
| | const char* what() const noexcept override;
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport FileException: public Exception
|
| | {
|
| | public:
|
| | explicit FileException(
|
| | const std::string& message = "Unknown file exception happened",
|
| | const std::string& fileName = ""
|
| | );
|
| | FileException(const std::string& message, const FileInfo& File);
|
| |
|
| | const char* what() const noexcept override;
|
| | void reportException() const override;
|
| | std::string getFileName() const;
|
| | PyObject* getPyObject() override;
|
| |
|
| | void setPyObject(PyObject* pydict) override;
|
| |
|
| | PyObject* getPyExceptionType() const override;
|
| |
|
| | private:
|
| | FileInfo file;
|
| |
|
| |
|
| | std::string _sErrMsgAndFileName;
|
| | void setFileName(const std::string& fileName);
|
| | };
|
| |
|
| | class BaseExport FileSystemError: public Exception
|
| | {
|
| | public:
|
| | explicit FileSystemError(const std::string& message = "File system error");
|
| | FileSystemError(const FileSystemError&) = default;
|
| | FileSystemError(FileSystemError&&) = default;
|
| |
|
| | ~FileSystemError() noexcept override = default;
|
| | FileSystemError& operator=(const FileSystemError&) = default;
|
| | FileSystemError& operator=(FileSystemError&&) = default;
|
| |
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| |
|
| | class BaseExport BadFormatError: public Exception
|
| | {
|
| | public:
|
| | explicit BadFormatError(const std::string& message = "Bad format error");
|
| | BadFormatError(const BadFormatError&) = default;
|
| | BadFormatError(BadFormatError&&) = default;
|
| |
|
| | ~BadFormatError() noexcept override = default;
|
| | BadFormatError& operator=(const BadFormatError&) = default;
|
| | BadFormatError& operator=(BadFormatError&&) = default;
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | #if defined(__GNUC__)
|
| |
|
| | class BaseExport MemoryException: public Exception, virtual public std::bad_alloc
|
| | #else
|
| | class BaseExport MemoryException: public Exception
|
| | #endif
|
| | {
|
| | public:
|
| | explicit MemoryException(const std::string& = "Not enough memory available");
|
| |
|
| | #if defined(__GNUC__)
|
| | const char* what() const noexcept override;
|
| | #endif
|
| |
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| |
|
| | class BaseExport AccessViolation: public Exception
|
| | {
|
| | public:
|
| | explicit AccessViolation(const std::string& message = "Access violation");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| |
|
| | class BaseExport AbnormalProgramTermination: public Exception
|
| | {
|
| | public:
|
| | explicit AbnormalProgramTermination(const std::string& message = "Abnormal program termination");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport UnknownProgramOption: public Exception
|
| | {
|
| | public:
|
| | explicit UnknownProgramOption(const std::string& message = "Unknown program option");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ProgramInformation: public Exception
|
| | {
|
| | public:
|
| | explicit ProgramInformation(const std::string& message = "Program information");
|
| | };
|
| |
|
| | class BaseExport TypeError: public Exception
|
| | {
|
| | public:
|
| | explicit TypeError(const std::string& message = "Type error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ValueError: public Exception
|
| | {
|
| | public:
|
| | explicit ValueError(const std::string& message = "Value error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| |
|
| | class BaseExport IndexError: public Exception
|
| | {
|
| | public:
|
| | explicit IndexError(const std::string& message = "Index error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport NameError: public Exception
|
| | {
|
| | public:
|
| | explicit NameError(const std::string& message = "Name error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ImportError: public Exception
|
| | {
|
| | public:
|
| | explicit ImportError(const std::string& message = "Import error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport AttributeError: public Exception
|
| | {
|
| | public:
|
| | explicit AttributeError(const std::string& message = "Attribute error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport PropertyError: public AttributeError
|
| | {
|
| | public:
|
| | explicit PropertyError(const std::string& message = "Property error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport RuntimeError: public Exception
|
| | {
|
| | public:
|
| | explicit RuntimeError(const std::string& message = "Runtime error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport BadGraphError: public RuntimeError
|
| | {
|
| | public:
|
| | explicit BadGraphError(const std::string& message = "Bad graph error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport NotImplementedError: public Exception
|
| | {
|
| | public:
|
| | explicit NotImplementedError(const std::string& message = "Not implemented error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ZeroDivisionError: public Exception
|
| | {
|
| | public:
|
| | explicit ZeroDivisionError(const std::string& message = "Zero division error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ReferenceError: public Exception
|
| | {
|
| | public:
|
| | explicit ReferenceError(const std::string& message = "Reference error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ExpressionError: public Exception
|
| | {
|
| | public:
|
| | explicit ExpressionError(const std::string& message = "Expression error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport ParserError: public Exception
|
| | {
|
| | public:
|
| | explicit ParserError(const std::string& message = "Parser error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport UnicodeError: public Exception
|
| | {
|
| | public:
|
| | explicit UnicodeError(const std::string& message = "Unicode error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport OverflowError: public Exception
|
| | {
|
| | public:
|
| | explicit OverflowError(const std::string& message = "Overflow error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport UnderflowError: public Exception
|
| | {
|
| | public:
|
| | explicit UnderflowError(const std::string& message = "Underflow error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport UnitsMismatchError: public Exception
|
| | {
|
| | public:
|
| | explicit UnitsMismatchError(const std::string& message = "Units mismatch error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport CADKernelError: public Exception
|
| | {
|
| | public:
|
| | explicit CADKernelError(const std::string& message = "CAD kernel error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | class BaseExport RestoreError: public Exception
|
| | {
|
| | public:
|
| | explicit RestoreError(const std::string& message = "Restore error");
|
| | PyObject* getPyExceptionType() const override;
|
| | };
|
| |
|
| | inline void Exception::setMessage(const std::string& message)
|
| | {
|
| | errorMessage = message;
|
| | }
|
| |
|
| | inline std::string Exception::getMessage() const
|
| | {
|
| | return errorMessage;
|
| | }
|
| |
|
| | inline std::string Exception::getFile() const
|
| | {
|
| | return fileName;
|
| | }
|
| |
|
| | inline int Exception::getLine() const
|
| | {
|
| | return lineNum;
|
| | }
|
| |
|
| | inline std::string Exception::getFunction() const
|
| | {
|
| | return functionName;
|
| | }
|
| |
|
| | inline bool Exception::getTranslatable() const
|
| | {
|
| | return isTranslatable;
|
| | }
|
| |
|
| | inline bool Exception::getReported() const
|
| | {
|
| | return hasBeenReported;
|
| | }
|
| |
|
| | inline void Exception::setReported(const bool reported) const
|
| | {
|
| | hasBeenReported = reported;
|
| | }
|
| |
|
| | #if defined(HAVE_STD_SOURCE_LOCATION)
|
| | inline void Exception::setDebugInformation(const std::source_location& location)
|
| | {
|
| | fileName = location.file_name();
|
| | lineNum = static_cast<int>(location.line());
|
| | functionName = location.function_name();
|
| | }
|
| | #else
|
| | inline void Exception::setDebugInformation(const char* file, int line, const char* func)
|
| | {
|
| | fileName = file;
|
| | lineNum = line;
|
| | functionName = func;
|
| | }
|
| | #endif
|
| |
|
| | inline void Exception::setTranslatable(const bool translatable)
|
| | {
|
| | isTranslatable = translatable;
|
| | }
|
| |
|
| | #if defined(__GNUC__) && defined(FC_OS_LINUX)
|
| | class SignalException
|
| | {
|
| | public:
|
| | SignalException();
|
| | ~SignalException();
|
| |
|
| | private:
|
| | static void throw_signal(int signum);
|
| |
|
| | struct sigaction new_action {};
|
| | struct sigaction old_action {};
|
| | bool ok {false};
|
| | };
|
| | #endif
|
| |
|
| | }
|
| |
|
| | #endif
|
| |
|