Loading files
ce705b508This 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
*
* @hidecallergraph
*/
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 invalidFileContent The parsed string which is invalid (optional)
* @param msg See Exception#Exception()
*/
FileParseError(const char* file, int line, const FilePath& filePath,
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