Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing library specific exception #55

Merged
merged 1 commit into from
Mar 8, 2024
Merged
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
24 changes: 24 additions & 0 deletions include/fprops/Exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "fmt/format.h"
#include <exception>

namespace fprops {

class Exception : public std::exception {
public:
template <typename... T>
Exception(fmt::format_string<T...> format, T... args) :
msg(fmt::format(format, std::forward<T>(args)...))
{
}

/// Get the exception message
[[nodiscard]] auto what() const noexcept -> const char * override;

private:
/// Error message
std::string msg;
};

} // namespace fprops
11 changes: 11 additions & 0 deletions src/Exception.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "fprops/Exception.h"

namespace fprops {

auto
Exception::what() const noexcept -> const char *
{
return this->msg.c_str();
}

} // namespace fprops
16 changes: 8 additions & 8 deletions src/Helmholtz.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "fprops/Helmholtz.h"
#include "fprops/Numerics.h"
#include "fprops/Exception.h"
#include <cmath>
#include <stdexcept>

namespace fprops {

Expand All @@ -18,9 +18,9 @@
Helmholtz::rho_T(double rho, double T) const
{
if (rho < 0)
throw std::domain_error("Negative density");
throw Exception("Negative density");
if (T < 0)

Check warning on line 22 in src/Helmholtz.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

src/Helmholtz.cpp:22:15 [readability-braces-around-statements]

statement should be inside braces
throw std::domain_error("Negative temperature");
throw Exception("Negative temperature");

const double delta = rho / this->rho_c;
const double tau = this->T_c / T;
Expand Down Expand Up @@ -50,7 +50,7 @@
Helmholtz::rho_p(double rho, double p) const
{
if (rho < 0)
throw std::domain_error("Negative density");
throw Exception("Negative density");

const double T = T_from_rho_p(rho, p);

Expand Down Expand Up @@ -81,7 +81,7 @@
Helmholtz::p_T(double p, double T) const
{
if (T < 0)
throw std::domain_error("Negative temperature");
throw Exception("Negative temperature");

const double rho = rho_from_p_T(p, T);

Expand Down Expand Up @@ -112,9 +112,9 @@
Helmholtz::v_u(double v, double u) const
{
if (v <= 0.)
throw std::domain_error("Negative specific volume");
throw Exception("Negative specific volume");
if (u <= 0.)

Check warning on line 116 in src/Helmholtz.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

src/Helmholtz.cpp:116:17 [readability-braces-around-statements]

statement should be inside braces
throw std::domain_error("Negative internal energy");
throw Exception("Negative internal energy");

const double rho = 1. / v;
const double delta = rho / this->rho_c;
Expand Down Expand Up @@ -143,7 +143,7 @@
State
Helmholtz::h_s(double h, double s) const
{
throw std::domain_error("Not implemented");
throw Exception("Not implemented");
}

double
Expand Down
24 changes: 12 additions & 12 deletions src/IdealGas.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "fprops/IdealGas.h"
#include "fprops/Exception.h"
#include <cmath>
#include <stdexcept>

namespace fprops {

Expand Down Expand Up @@ -35,9 +35,9 @@
IdealGas::rho_T(double rho, double T) const
{
if (rho < 0)
throw std::domain_error("Negative density");
throw Exception("Negative density");
if (T < 0)

Check warning on line 39 in src/IdealGas.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

src/IdealGas.cpp:39:15 [readability-braces-around-statements]

statement should be inside braces
throw std::domain_error("Negative temperature");
throw Exception("Negative temperature");

State state;
state.rho = rho;
Expand All @@ -51,7 +51,7 @@
state.v = 1. / state.rho;
const double n = std::pow(T, this->gamma) / std::pow(state.p, this->gamma - 1.0);
if (n <= 0)
throw std::domain_error("Invalid log base for computing entropy");
throw Exception("Invalid log base for computing entropy");
state.s = this->cv * std::log(n);
state.h = this->cp * T;
state.w = std::sqrt(this->cp * R * T / (this->cv * this->molar_mass));
Expand All @@ -62,7 +62,7 @@
IdealGas::rho_p(double rho, double p) const
{
if (rho < 0)
throw std::domain_error("Negative density");
throw Exception("Negative density");

State state;
state.rho = rho;
Expand All @@ -76,7 +76,7 @@
state.v = 1. / state.rho;
const double n = std::pow(state.T, this->gamma) / std::pow(state.p, this->gamma - 1.0);
if (n <= 0)
throw std::domain_error("Invalid log base for computing entropy");
throw Exception("Invalid log base for computing entropy");
state.s = this->cv * std::log(n);
state.h = this->cp * state.T;
state.w = std::sqrt(this->cp * R * state.T / (this->cv * this->molar_mass));
Expand All @@ -87,7 +87,7 @@
IdealGas::p_T(double p, double T) const
{
if (T < 0)
throw std::domain_error("Negative temperature");
throw Exception("Negative temperature");

State state;
state.p = p;
Expand All @@ -101,7 +101,7 @@
state.v = 1. / state.rho;
const double n = std::pow(T, this->gamma) / std::pow(p, this->gamma - 1.0);
if (n <= 0)
throw std::domain_error("Invalid log base for computing entropy");
throw Exception("Invalid log base for computing entropy");
state.s = this->cv * std::log(n);
state.h = this->cp * T;
state.w = std::sqrt(this->cp * R * T / (this->cv * this->molar_mass));
Expand All @@ -112,9 +112,9 @@
IdealGas::v_u(double v, double u) const
{
if (v <= 0.)
throw std::domain_error("Negative specific volume");
throw Exception("Negative specific volume");
if (u <= 0.)

Check warning on line 116 in src/IdealGas.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

src/IdealGas.cpp:116:17 [readability-braces-around-statements]

statement should be inside braces
throw std::domain_error("Negative internal energy");
throw Exception("Negative internal energy");

State state;
state.v = v;
Expand All @@ -128,7 +128,7 @@
state.T = u / this->cv;
const double n = std::pow(state.T, this->gamma) / std::pow(state.p, this->gamma - 1.0);
if (n <= 0)
throw std::domain_error("Invalid log base for computing entropy");
throw Exception("Invalid log base for computing entropy");
state.s = this->cv * std::log(n);
state.h = this->cp * state.T;
state.w = std::sqrt(this->gamma * this->R_specific * state.T);
Expand All @@ -154,7 +154,7 @@
state.v = 1. / state.rho;
const double n = std::pow(state.T, this->gamma) / std::pow(state.p, this->gamma - 1.0);
if (n <= 0)
throw std::domain_error("Invalid log base for computing entropy");
throw Exception("Invalid log base for computing entropy");
state.w = std::sqrt(this->gamma * this->R_specific * state.T);
return state;
}
Expand Down
17 changes: 9 additions & 8 deletions src/InterpolatedFluidProperties.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "fprops/InterpolatedFluidProperties.h"
#include "fprops/Utils.h"
#include "fprops/Numerics.h"
#include "fprops/Exception.h"
#include "h5pp/h5pp.h"
#include "fmt/printf.h"
#include "Eigen/Dense"
Expand Down Expand Up @@ -50,7 +51,7 @@ InterpolatedFluidProperties::load(const std::string & file_name)
this->hs_data = read_data(file, "h_s", { H, S }, { U, V, P, T, RHO, MU, CP, CV, K, W });
}
else
throw std::runtime_error(fmt::format("File '{}' does not exist.", file_name));
throw Exception("File '{}' does not exist.", file_name);
}

State
Expand All @@ -62,7 +63,7 @@ InterpolatedFluidProperties::p_T(double p, double T) const
vals[CP], vals[CV], vals[S], vals[K], vals[H], vals[W] };
}
else
throw std::runtime_error("'p_T' data set is missing.");
throw Exception("'p_T' data set is missing.");
}

State
Expand All @@ -74,7 +75,7 @@ InterpolatedFluidProperties::rho_T(double rho, double T) const
vals[CP], vals[CV], vals[S], vals[K], vals[H], vals[W] };
}
else
throw std::runtime_error("'rho_T' data set is missing.");
throw Exception("'rho_T' data set is missing.");
}

State
Expand All @@ -86,7 +87,7 @@ InterpolatedFluidProperties::rho_p(double rho, double p) const
vals[CP], vals[CV], vals[S], vals[K], vals[H], vals[W] };
}
else
throw std::runtime_error("'rho_p' data set is missing.");
throw Exception("'rho_p' data set is missing.");
}

State
Expand All @@ -98,7 +99,7 @@ InterpolatedFluidProperties::v_u(double v, double u) const
vals[CP], vals[CV], vals[S], vals[K], vals[H], vals[W] };
}
else
throw std::runtime_error("'v_u' data set is missing.");
throw Exception("'v_u' data set is missing.");
}

State
Expand All @@ -110,7 +111,7 @@ InterpolatedFluidProperties::h_s(double h, double s) const
vals[CP], vals[CV], s, vals[K], h, vals[W] };
}
else
throw std::runtime_error("'h_s' data set is missing.");
throw Exception("'h_s' data set is missing.");
}

void
Expand All @@ -120,7 +121,7 @@ InterpolatedFluidProperties::check_unit(const h5pp::File & file,
{
auto attr = file.readAttribute<std::string>(dataset_name, "unit");
if (attr != unit)
throw std::runtime_error(fmt::format("Expected unit '{}' for '{}'.", unit, dataset_name));
throw Exception("Expected unit '{}' for '{}'.", unit, dataset_name);
}

Eigen::VectorXd
Expand All @@ -133,7 +134,7 @@ InterpolatedFluidProperties::read_var_range(const h5pp::File & file,
check_unit(file, nm, this->var_units[var_idx]);
file.readDataset(range, nm);
if (range.size() < 2)
throw std::runtime_error(
throw Exception(
fmt::format("'{}' range must have 2 or more grid points.", this->var_names[var_idx]));
return range;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Numerics.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "fprops/Numerics.h"
#include "fprops/Exception.h"
#include <cmath>
#include <stdexcept>

namespace fprops {

Expand Down Expand Up @@ -29,7 +29,7 @@ root(double x0,
x0 = x1;
}

throw std::runtime_error("Newton's method failed to converge");
throw Exception("Newton's method failed to converge");
}

} // namespace newton
Expand Down
28 changes: 28 additions & 0 deletions test/src/ExceptionTestMacros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "fprops/Exception.h"

/// Test that the `cmd` will throw `fprops::Exception` with message `msg`
#define EXPECT_THROW_MSG(cmd, msg) \

Check warning on line 6 in test/src/ExceptionTestMacros.h

View workflow job for this annotation

GitHub Actions / c++ linter

test/src/ExceptionTestMacros.h:6:9 [cppcoreguidelines-macro-usage]

function-like macro 'EXPECT_THROW_MSG' used; consider a 'constexpr' template function
try { \
cmd; \
FAIL(); \
} \
catch (Exception & e) { \
EXPECT_STREQ(e.what(), msg); \
} \
catch (...) { \
FAIL(); \
}

#define EXPECT_THAT_THROW_MSG(cmd, matcher) \

Check warning on line 18 in test/src/ExceptionTestMacros.h

View workflow job for this annotation

GitHub Actions / c++ linter

test/src/ExceptionTestMacros.h:18:9 [cppcoreguidelines-macro-usage]

function-like macro 'EXPECT_THAT_THROW_MSG' used; consider a 'constexpr' template function
try { \
cmd; \
FAIL(); \
} \
catch (Exception & e) { \
EXPECT_THAT(e.what(), matcher); \
} \
catch (...) { \
FAIL(); \
}
3 changes: 2 additions & 1 deletion test/src/Helium_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "gtest/gtest.h"
#include "ExceptionTestMacros.h"
#include "fprops/Helium.h"

using namespace fprops;
Expand Down Expand Up @@ -95,7 +96,7 @@
double p = 1.0e6;
auto state0 = fp.p_T(p, T);

EXPECT_THROW(auto f = fp.v_u(state0.v, state0.u), std::runtime_error);
EXPECT_THROW_MSG(auto f = fp.v_u(state0.v, state0.u), "Newton's method failed to converge");

Check warning on line 99 in test/src/Helium_test.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

test/src/Helium_test.cpp:99:27 [readability-identifier-length]

variable name 'f' is too short, expected at least 3 characters
/*
State state = fp.v_u(state0.v, state0.u);

Expand Down
15 changes: 8 additions & 7 deletions test/src/Helmholtz_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "gmock/gmock.h"
#include "ExceptionTestMacros.h"
#include "fprops/Helmholtz.h"

using namespace fprops;
Expand Down Expand Up @@ -26,37 +27,37 @@
{
MockHelmholtz fp;

EXPECT_THROW(auto p = fp.rho_T(-1, 300), std::domain_error);
EXPECT_THROW(auto p = fp.rho_T(1, -1), std::domain_error);
EXPECT_THROW_MSG(auto p = fp.rho_T(-1, 300), "Negative density");

Check warning on line 30 in test/src/Helmholtz_test.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

test/src/Helmholtz_test.cpp:30:27 [readability-identifier-length]

variable name 'p' is too short, expected at least 3 characters
EXPECT_THROW_MSG(auto p = fp.rho_T(1, -1), "Negative temperature");

Check warning on line 31 in test/src/Helmholtz_test.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

test/src/Helmholtz_test.cpp:31:27 [readability-identifier-length]

variable name 'p' is too short, expected at least 3 characters
}

TEST(HelmholtzTest, rho_p_incorrect)
{
MockHelmholtz fp;

EXPECT_THROW(auto p = fp.rho_p(-1, 300), std::domain_error);
EXPECT_THROW_MSG(auto p = fp.rho_p(-1, 300), "Negative density");

Check warning on line 38 in test/src/Helmholtz_test.cpp

View workflow job for this annotation

GitHub Actions / c++ linter

test/src/Helmholtz_test.cpp:38:27 [readability-identifier-length]

variable name 'p' is too short, expected at least 3 characters
}

TEST(HelmholtzTest, h_s)
{
MockHelmholtz fp;

EXPECT_THROW(auto p = fp.h_s(1, 1), std::domain_error);
EXPECT_THROW_MSG(auto p = fp.h_s(1, 1), "Not implemented");
}

TEST(HelmholtzTest, p_T_incorrect)
{
MockHelmholtz fp;

EXPECT_THROW(auto p = fp.p_T(1e5, -1), std::domain_error);
EXPECT_THROW_MSG(auto p = fp.p_T(1e5, -1), "Negative temperature");
}

TEST(HelmholtzTest, v_u_incorrect)
{
MockHelmholtz fp;

EXPECT_THROW(auto p = fp.v_u(-1, 1), std::domain_error);
EXPECT_THROW(auto p = fp.v_u(1, -1), std::domain_error);
EXPECT_THROW_MSG(auto st = fp.v_u(-1, 1), "Negative specific volume");
EXPECT_THROW_MSG(auto st = fp.v_u(1, -1), "Negative internal energy");
}

TEST(HelmholtzTest, ideal_gas_lead)
Expand Down
Loading
Loading