Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apps/PQ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
#include <string> // for string, char_traits
#include <vector> // for vector

#include "baseException.hpp"
#include "capabilities.hpp" // for writeCapabilities
#include "commandLineArgs.hpp" // for CommandLineArgs
#include "driver.hpp"
#include "exceptions.hpp" // for CustomException
#include "systemInfo.hpp" // for _VERSION_
#include "validation.hpp" // for validation

Expand Down Expand Up @@ -80,7 +80,7 @@ int main(int argc, char *argv[])
{
commandLineArgs.parse();
}
catch (const customException::CustomException &e)
catch (const exc::PQException &e)
{
std::cerr << "Error: " << e.getMessage() << '\n' << std::flush;
return EXIT_FAILURE;
Expand Down Expand Up @@ -145,7 +145,7 @@ int main(int argc, char *argv[])
{
driver::Driver().run(commandLineArgs.getInputFileName());
}
catch (const customException::CustomException &e)
catch (const exc::PQException &e)
{
std::cerr << "Error: " << e.getMessage() << '\n' << std::flush;
exitCode = EXIT_FAILURE;
Expand Down
22 changes: 11 additions & 11 deletions apps/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace
{
if (!std::filesystem::is_regular_file(fileName))
{
throw customException::InputFileException(
throw exc::InputFileException(
std::format(
"{} \"{}\" does not exist or is not a regular file",
description,
Expand All @@ -112,7 +112,7 @@ namespace
{
if (!std::filesystem::is_directory(directoryName))
{
throw customException::InputFileException(
throw exc::InputFileException(
std::format(
"{} \"{}\" does not exist or is not a directory",
description,
Expand Down Expand Up @@ -177,15 +177,15 @@ namespace

if (script.empty() && fullPathScript.empty())
{
throw customException::InputFileException(
throw exc::InputFileException(
"No qm_script provided. Please provide a qm_script in the "
"input file."
);
}

if (!script.empty() && !fullPathScript.empty())
{
throw customException::InputFileException(
throw exc::InputFileException(
"\"qm_script\" and \"qm_script_full_path\" are mutually "
"exclusive"
);
Expand All @@ -194,7 +194,7 @@ namespace
if (!script.empty() &&
!cli::isExternalQMScript(QMSettings::getQMMethod(), script))
{
throw customException::InputFileException(
throw exc::InputFileException(
std::format(
"Bundled QM script \"{}\" is not available for {}",
script,
Expand Down Expand Up @@ -225,7 +225,7 @@ namespace

if (isStaticBuild && fullPathScript.empty())
{
throw customException::InputFileException(
throw exc::InputFileException(
"This PQ build requires \"qm_script_full_path\" for "
"external QM programs"
);
Expand Down Expand Up @@ -263,20 +263,20 @@ namespace
if (engine.isConstraintsActivated() || ForceFieldSettings::isActive())
{
if (!FileSettings::isTopologyFileNameSet())
throw customException::InputFileException(
throw exc::InputFileException(
"Topology file needed for requested simulation setup"
);
}

if (ForceFieldSettings::isActive() &&
!FileSettings::isParameterFileNameSet())
throw customException::InputFileException(
throw exc::InputFileException(
"Parameter file needed for requested simulation setup"
);

if (engine.getConstraints()->isMShakeActive() &&
FileSettings::getMShakeFileName().empty())
throw customException::InputFileException(
throw exc::InputFileException(
"M-SHAKE file needed for requested simulation setup"
);

Expand Down Expand Up @@ -387,7 +387,7 @@ namespace
method == settings::QMMethod::FENNOL ||
method == settings::QMMethod::MACE)
{
throw customException::InputFileException(
throw exc::InputFileException(
std::format(
"QM method {} requires ASE support, but this PQ build "
"does not include it",
Expand Down Expand Up @@ -507,7 +507,7 @@ cli::ValidationResult cli::validateInputFile(
appendWarnings(reader, result);
return result;
}
catch (const customException::CustomException &exception)
catch (const exc::PQException &exception)
{
return invalidResult(
inputFile,
Expand Down
1 change: 1 addition & 0 deletions changes/developer/enhancement.exceptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- add new exception handling approach via tempalted NTTP for color and type, which makes handling of new exception types much easier
2 changes: 1 addition & 1 deletion changes/user/bugfix.throw-when-qm-runner-fails.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- Throw a customException::QMRunnerException when an external QM runner does not finish successfully
- Throw a exc::QMRunnerException when an external QM runner does not finish successfully
104 changes: 104 additions & 0 deletions include/exceptions/baseException.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*****************************************************************************
<GPL_HEADER>

PQ
Copyright (C) 2023-now Jakob Gamper

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/>.

<GPL_HEADER>
******************************************************************************/

#ifndef _BASE_EXCEPTION_HPP_
#define _BASE_EXCEPTION_HPP_

#include "color.hpp"
#include "exceptionTypes.hpp"

namespace exc
{
/**
* @class PQException
*
* @brief Base class for all custom exceptions in the application
*
* This class serves as a base for all custom exceptions in the application.
* It inherits from std::exception and provides a common interface for
* exception handling.
*/
class PQException : public std::exception
{
private:
std::string _message;
std::optional<size_t> _lineNumber;

public:
explicit PQException(const std::string_view message);
explicit PQException(
const std::string_view message,
std::optional<size_t> lineNumber
);

void setLineNumber(const size_t lineNumber) noexcept;

[[nodiscard]]
const std::string &getMessage() const noexcept;

[[nodiscard]]
std::optional<size_t> getLineNumber() const noexcept;
};

/**
* @class BaseException
*
* @brief Base class for custom exceptions
*
* This class serves as a base for all custom exceptions in the application.
* It provides common functionality such as message handling, line number
* tracking, and colorful output for exception messages.
*
* @tparam Color The color code for the exception message output
* @tparam Type The type of exception being thrown
*/
template <
Color::Code colorCode = Color::FG_RED,
ExceptionType exceptionType = ExceptionType::Undefined>
class BaseException : public PQException
{
private:
static constexpr Color::Code _color = colorCode;
static constexpr ExceptionType _type = exceptionType;

public:
explicit BaseException(
const std::string_view message,
std::optional<size_t> lineNumber
);
explicit BaseException(const std::string_view message);

[[nodiscard]]
const char *what() const noexcept override;

static void colorfulOutput(
const Color::Code color,
const std::string_view message
);
};
} // namespace exc

#ifndef _BASE_EXCEPTION_TPP_
#include "baseException.tpp"
#endif // _BASE_EXCEPTION_TPP_

#endif // _BASE_EXCEPTION_HPP_
97 changes: 97 additions & 0 deletions include/exceptions/baseException.tpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*****************************************************************************
<GPL_HEADER>

PQ
Copyright (C) 2023-now Jakob Gamper

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/>.

<GPL_HEADER>
******************************************************************************/

#ifndef _BASE_EXCEPTION_TPP_
#define _BASE_EXCEPTION_TPP_

#include <iostream>

#include "baseException.hpp"

namespace exc
{
/**
* @brief Construct a new Custom Exception:: Custom Exception object
*
* @param message
*/
template <Color::Code colorCode, ExceptionType exceptionType>
BaseException<colorCode, exceptionType>::BaseException(
const std::string_view message,
std::optional<size_t> lineNumber
)
: PQException(message, lineNumber)
{
}

/**
* @brief Construct a new Custom Exception:: Custom Exception object
*
* @param message
*/
template <Color::Code colorCode, ExceptionType exceptionType>
BaseException<colorCode, exceptionType>::BaseException(
const std::string_view message
)
: PQException(message, std::nullopt)
{
}

/**
* @brief Prints the exceptionMsg type in color.
*
* @param color
* @param exceptionMsg
*/
template <Color::Code colorCode, ExceptionType exceptionType>
void BaseException<colorCode, exceptionType>::colorfulOutput(
const Color::Code color,
const std::string_view exceptionMsg
)
{
const Color::Modifier modifier(color);
const Color::Modifier def(Color::FG_DEFAULT);

std::cout << modifier << exceptionMsg << def << '\n' << std::flush;
}

/**
* @brief Construct a new Custom Exception:: Custom Exception object
*
* @return const char*
*/
template <Color::Code colorCode, ExceptionType exceptionType>
const char *BaseException<colorCode, exceptionType>::what() const noexcept
{
if (exceptionType != ExceptionType::Undefined)
{
colorfulOutput(
colorCode,
ExceptionTypeMeta::toString(exceptionType)
);
}

return PQException::getMessage().c_str();
}
} // namespace exc

#endif // _BASE_EXCEPTION_TPP_
59 changes: 59 additions & 0 deletions include/exceptions/exceptionTypes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*****************************************************************************
<GPL_HEADER>

PQ
Copyright (C) 2023-now Jakob Gamper

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/>.

<GPL_HEADER>
******************************************************************************/

#ifndef _EXCEPTION_TYPES_HPP_
#define _EXCEPTION_TYPES_HPP_

#include <cstdint>
#include <mstd/enum.hpp>

#define EXCEPTION_TYPES(X) \
X(Undefined) \
X(InputFileError) \
X(RstFileError) \
X(UserInputError) \
X(MoldescriptorError) \
X(UserInputWarning) \
X(GuffDatError) \
X(TopologyError) \
X(ParameterFileError) \
X(ManostatError) \
X(IntraNonBondedError) \
X(ShakeError) \
X(CellListError) \
X(RingPolymerRestartFileError) \
X(QmRunnerError) \
X(MpiError) \
X(QmRuntimeExceeded) \
X(MShakeFileError) \
X(MShakeError) \
X(LinearAlgebraError) \
X(OptimizationError) \
X(OptimizationWarning) \
X(CompileTimeError) \
X(HybridConfiguratorError) \
X(HybridMDEngineError) \
X(TimerError)

MSTD_ENUM(ExceptionType, std::uint8_t, EXCEPTION_TYPES)

#endif // _EXCEPTION_TYPES_HPP_
Loading