Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
d953b88eaThis file is pinned to the selected release. Download the original to open it in your design tool.
/*
* LibrePCB - Professional EDA for everyone!
* Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
* https://librepcb.org/
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBREPCB_CORE_EXCEPTIONS_H
#define LIBREPCB_CORE_EXCEPTIONS_H
/*******************************************************************************
* Includes
******************************************************************************/
#include <QtCore>
/*******************************************************************************
* Namespace / Forward Declarations
******************************************************************************/
namespace librepcb {
class FilePath;
/*******************************************************************************
* Class Exception
******************************************************************************/
/**
* @brief The Exception class
*
* This is an exception base class. It inherits from the QException class, which
* implements an exception class which can be transferred across threads.
* QException inherits from std::exception. There are several subclasses of the
* class Exception, see inheritance diagram.
*
* @note Exceptions must always be thrown by value and caught by (const)
* reference!
*
* For more information about the QException class read the Qt documentation.
*
* Each Exception object holds following attributes:
* - a message (#mMsg): error message in the user's language (can be printed
* directly to a QMessageBox or similar)
* - the filename of the source file where the exception was thrown (#mFile)
* - the line number where the exception was thrown (#mLine)
*
* @note Every exception will automatically print a debug message (see
* librepcb::Debug) of type librepcb::Debug::DebugLevel_t::Exception.
*
* Example how to use exceptions:
*
* @code
* void foo(int i) {
* if (i < 0) {
* throw Exception(__FILE__, __LINE__, tr("Invalid argument: %1").arg(i));
* }
* }
*
* void bar() noexcept {
* try {
* foo(-5);
* } catch (const Exception& e) {
* QMessageBox::critical(0, tr("Error"), e.getMsg());
* }
* }
* @endcode
*
* @warning Please read the "Exception Safety" notes from the Qt Project
* documentation before writing source code which throws exceptions, there are
* some important things to know:
* http://qt-project.org/doc/qt-5/exceptionsafety.html
*/
class Exception : public QException {
public:
// Constructors / Destructor
/**
* @brief The default constructor
*/
Exception() = delete;
/**
* @brief The copy constructor (needed for #clone())
*/
Exception(const Exception& other) noexcept;
/**
* @brief The constructor which is used to throw an exception
*
* @param file The source file where the exception was thrown (use
* __FILE__)
* @param line The line number where the exception was thrown (use
* __LINE__)
* @param msg An error message in the user's language (use
* QObject::tr()). This message can be used in message boxes.
*/
Exception(const char* file, int line,
const QString& msg = QString("Exception")) noexcept;
/**
* @brief The destructor
*/
virtual ~Exception() noexcept {}
// Getters
/**
* @brief Get the error message (translated)
*
* @return The error message in the user's language
*/
const QString& getMsg() const { return mMsg; }
/**
* @brief Get the source file where the exception was thrown
*
* @return The filename
*/
const QString& getFile() const { return mFile; }
/**
* @brief Get the line number where the exception was thrown
*
* @return The line number
*/
int getLine() const { return mLine; }
/**
* @brief reimplemented from std::exception::what()
*
* @warning This method is only for compatibility reasons with the base class
* std::exception. Normally, you should not use this method.
* Use #getMsg() instead.
*
* @note The returned pointer is valid as long as the exception object exists
*
* @return the error message as a C-string (const char*) in the local encoding
*/
const char* what() const noexcept override;
// Inherited from QException (see QException documentation for more details)
virtual void raise() const override { throw *this; }
virtual Exception* clone() const override { return new Exception(*this); }
private:
// Attributes
QString mMsg; ///< the error message (translated)
QString mFile; ///< the source filename where the exception was thrown
int mLine; ///< the line number where the exception was thrown
// Cached Attributes
mutable QByteArray mMsgUtf8; ///< the message as an UTF8 byte array
};
/*******************************************************************************
* Class LogicError
******************************************************************************/
/**
* @brief The LogicError class
*
* This exception class is used for exceptions related to the internal logic of
* the program (a thrown LogicError means that there is a bug in the source
* code).
*
* @see Exception
*/
class LogicError final : public Exception {
public:
/**
* @brief Default Constructor
*/
LogicError() = delete;
/**
* @copydoc Exception::Exception
*/
LogicError(const char* file, int line,
const QString& msg = QString("Logic Error")) noexcept;
/**
* @brief The copy constructor (needed for #clone())
*/
LogicError(const LogicError& other) noexcept;
// Inherited from Exception
virtual void raise() const override { throw *this; }
virtual LogicError* clone() const override { return new LogicError(*this); }
};
/*******************************************************************************
* Class RuntimeError
******************************************************************************/
/**
* @brief The RuntimeError class
*
* This exception class is used for exceptions detected during runtime, but are
* not produced because of bugs in the source code. For example if you want to
* write to a file but the user has no write permissions, this can be a runtime
* error.
*
* @see Exception
*/
class RuntimeError : public Exception {
public:
/**
* @brief Default Constructor
*/
RuntimeError() = delete;
/**
* @copydoc Exception::Exception
*/
RuntimeError(const char* file, int line,
const QString& msg = QString("Runtime Error")) noexcept;
/**
* @brief The copy constructor (needed for #clone())
*/
RuntimeError(const RuntimeError& other) noexcept;
/**
* @brief Destructor
*/
virtual ~RuntimeError() noexcept {}
// Inherited from Exception
virtual void raise() const override { throw *this; }
virtual RuntimeError* clone() const override {
return new RuntimeError(*this);
}
};
/*******************************************************************************
* Class RangeError
******************************************************************************/
/**
* @brief The RangeError class
*
* This exception class is used for range under-/overflows.
*
* @see Exception
*/
class RangeError final : public RuntimeError {
public:
/**
* @brief Default Constructor
*/
RangeError() = delete;
/**
* @copydoc Exception::Exception
*/
RangeError(const char* file, int line,
const QString& msg = QString("Range Error")) noexcept;
/**
* Constructor which produces a message like "42 not in range [13..37]"
*
* @param file See ::librepcb::Exception::Exception()
* @param line See ::librepcb::Exception::Exception()
* @param value The invalid value
* @param min The lower value limit
* @param max The upper value limit
*/
template <typename Tval, typename Tmin, typename Tmax>
RangeError(const char* file, int line, const Tval& value, const Tmin& min,
const Tmax& max) noexcept
: RangeError(file, line,
QString("Range error: %1 not in [%2..%3]")
.arg(value)
.arg(min)
.arg(max)) {}
/**
* @brief The copy constructor (needed for #clone())
*/
RangeError(const RangeError& other) noexcept;
// Inherited from RuntimeError
virtual void raise() const override { throw *this; }
virtual RangeError* clone() const override { return new RangeError(*this); }
};
/*******************************************************************************
* Class FileParseError
******************************************************************************/
/**
* @brief The FileParseError class
*
* This exception class is used for errors while parsing files due to invalid
* file content (for example invalid syntax).
*
* @see Exception
*/
class FileParseError final : public RuntimeError {
public:
/**
* @brief Default Constructor
*/
FileParseError() = delete;
/**
* @brief The constructor which is used to throw an exception
*
* @param file See ::librepcb::Exception::Exception()
* @param line See ::librepcb::Exception::Exception()
* @param filePath The path to the parsed file (optional)
* @param fileLine The line number of the parse error (-1 if
* unknown)
* @param fileColumn The column of the parse error (-1 if unknown)
* @param invalidFileContent The parsed string which is invalid (optional)
* @param msg See Exception#Exception()
*/
FileParseError(const char* file, int line, const FilePath& filePath,
int fileLine = -1, int fileColumn = -1,
const QString& invalidFileContent = QString(),
const QString& msg = QString("File Parse Error")) noexcept;
/**
* @brief The copy constructor (needed for #clone())
*/
FileParseError(const FileParseError& other) noexcept;
// Inherited from RuntimeError
virtual void raise() const override { throw *this; }
virtual FileParseError* clone() const override {
return new FileParseError(*this);
}
};
/*******************************************************************************
* Class UserCanceled
******************************************************************************/
/**
* @brief The UserCanceled class
*
* This exception class is used to interrupt an action which was canceled by the
* user. This type of exception is useful if the exception catcher do not need
* to show a message box with the error message. For example, if a project is
* opened, the project's constructor will throw an exception in case of an
* error. Then the caller (the catcher of the exception) will show a message box
* with the error message. But the constructor can also throw an exception if
* the user has canceled opening the project (for example in a message box
* "restore project?" --> YES|NO|CANCEL). But then the error message box do not
* need to appear! So we can throw an exception of type "UserCanceled" to
* indicate that this was a user's decision and the catcher will not show an
* error message box.
*
* @note Normally, a UserCanceled exception do not need the attribute #mMsg,
* so you do not need to pass the parameter "msg" to the constructor. This is
* because such an exception will never produce a message box with the error
* message (as there is not really an error - the user has simply canceled
* something).
*
* @see Exception
*/
class UserCanceled final : public Exception {
public:
/**
* @brief Default Constructor
*/
UserCanceled() = delete;
/**
* @copydoc Exception::Exception
*/
UserCanceled(const char* file, int line,
const QString& msg = QString("User Canceled")) noexcept;
/**
* @brief The copy constructor (needed for #clone())
*/
UserCanceled(const UserCanceled& other) noexcept;
// Inherited from Exception
virtual void raise() const override { throw *this; }
virtual UserCanceled* clone() const override {
return new UserCanceled(*this);
}
};
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace librepcb
#endif