Skip to content

Commit

Permalink
Use SCRAM_THROW instead of 'throw' statement
Browse files Browse the repository at this point in the history
The macro adds function, source line and file information
to the diagnostic information.
This is similar to BOOST_THROW_EXCEPTION,
but it only works with SCRAM exceptions.

Issue #219
  • Loading branch information
rakhimov committed Oct 15, 2017
1 parent 442b788 commit 86632fa
Show file tree
Hide file tree
Showing 21 changed files with 229 additions and 203 deletions.
6 changes: 3 additions & 3 deletions src/alignment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace mef {
Phase::Phase(std::string name, double time_fraction)
: Element(std::move(name)), time_fraction_(time_fraction) {
if (time_fraction_ <= 0 || time_fraction_ > 1)
throw DomainError("The phase fraction must be in (0, 1].");
SCRAM_THROW(DomainError("The phase fraction must be in (0, 1]."));
}

void Alignment::Add(PhasePtr phase) {
Expand All @@ -42,8 +42,8 @@ void Alignment::Validate() {
for (const PhasePtr& phase : phases_)
sum += phase->time_fraction();
if (!ext::is_close(1, sum, 1e-4))
throw ValidityError("The phases of alignment '" + Element::name() +
"' do not sum to 1.");
SCRAM_THROW(ValidityError("The phases of alignment '" + Element::name() +
"' do not sum to 1."));
}

} // namespace mef
Expand Down
51 changes: 27 additions & 24 deletions src/ccf_group.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,26 @@ CcfEvent::CcfEvent(std::string name, const CcfGroup* ccf_group)

void CcfGroup::AddMember(BasicEvent* basic_event) {
if (distribution_ || factors_.empty() == false) {
throw LogicError("No more members accepted. The distribution for " +
Element::name() + " CCF group has already been defined.");
SCRAM_THROW(LogicError("No more members accepted. The distribution for " +
Element::name() +
" CCF group has already been defined."));
}
if (ext::any_of(members_, [&basic_event](BasicEvent* member) {
return member->name() == basic_event->name();
})) {
throw DuplicateArgumentError("Duplicate member " + basic_event->name() +
" in " + Element::name() + " CCF group.");
SCRAM_THROW(DuplicateArgumentError("Duplicate member " +
basic_event->name() + " in " +
Element::name() + " CCF group."));
}
members_.push_back(basic_event);
}

void CcfGroup::AddDistribution(Expression* distr) {
if (distribution_)
throw LogicError("CCF distribution is already defined.");
SCRAM_THROW(LogicError("CCF distribution is already defined."));
if (members_.size() < 2) {
throw ValidityError(Element::name() +
" CCF group must have at least 2 members.");
SCRAM_THROW(ValidityError(Element::name() +
" CCF group must have at least 2 members."));
}
distribution_ = distr;
// Define probabilities of all basic events.
Expand All @@ -69,26 +71,26 @@ void CcfGroup::AddFactor(Expression* factor, boost::optional<int> level) {
level = prev_level_ ? (prev_level_ + 1) : min_level;

if (*level <= 0 || members_.empty())
throw LogicError("Invalid CCF group factor setup.");
SCRAM_THROW(LogicError("Invalid CCF group factor setup."));

if (*level < min_level) {
throw ValidityError("The CCF factor level (" + std::to_string(*level) +
") is less than the minimum level (" +
std::to_string(min_level) + ") required by " +
Element::name() + " CCF group.");
SCRAM_THROW(ValidityError(
"The CCF factor level (" + std::to_string(*level) +
") is less than the minimum level (" + std::to_string(min_level) +
") required by " + Element::name() + " CCF group."));
}
if (members_.size() < *level) {
throw ValidityError("The CCF factor level " + std::to_string(*level) +
" is more than the number of members (" +
std::to_string(members_.size()) + ") in " +
Element::name() + " CCF group.");
SCRAM_THROW(ValidityError("The CCF factor level " + std::to_string(*level) +
" is more than the number of members (" +
std::to_string(members_.size()) + ") in " +
Element::name() + " CCF group."));
}

int index = *level - min_level;
if (index < factors_.size() && factors_[index].second != nullptr) {
throw RedefinitionError("Redefinition of CCF factor for level " +
std::to_string(*level) + " in " + Element::name() +
" CCF group.");
SCRAM_THROW(RedefinitionError("Redefinition of CCF factor for level " +
std::to_string(*level) + " in " +
Element::name() + " CCF group."));
}
if (index >= factors_.size())
factors_.resize(index + 1);
Expand All @@ -99,15 +101,16 @@ void CcfGroup::AddFactor(Expression* factor, boost::optional<int> level) {

void CcfGroup::Validate() const {
if (!distribution_ || members_.empty() || factors_.empty())
throw LogicError("CCF group " + Element::name() + " is not initialized.");
SCRAM_THROW(
LogicError("CCF group " + Element::name() + " is not initialized."));

EnsureProbability(distribution_,
Element::name() + " CCF group distribution.");

for (const std::pair<int, Expression*>& f : factors_) {
if (!f.second) {
throw ValidityError("Missing some CCF factors for " + Element::name() +
" CCF group.");
SCRAM_THROW(ValidityError("Missing some CCF factors for " +
Element::name() + " CCF group."));
}
EnsureProbability(f.second, Element::name() + " CCF group factors.",
"fraction");
Expand Down Expand Up @@ -271,8 +274,8 @@ void PhiFactorModel::DoValidate() const {
}
if (!ext::is_close(1, sum, 1e-4) || !ext::is_close(1, sum_min, 1e-4) ||
!ext::is_close(1, sum_max, 1e-4)) {
throw ValidityError("The factors for Phi model " + CcfGroup::name() +
" CCF group must sum to 1.");
SCRAM_THROW(ValidityError("The factors for Phi model " + CcfGroup::name() +
" CCF group must sum to 1."));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Config::Config(const std::string& config_file) {
static xml::Validator validator(Env::config_schema());

if (fs::exists(config_file) == false) {
throw IOError("The configuration file does not exist.")
SCRAM_THROW(IOError("The configuration file does not exist."))
<< boost::errinfo_file_name(config_file);
}

Expand Down
5 changes: 3 additions & 2 deletions src/cycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,9 @@ void CheckCycle(const SinglePassRange& container, const char* type) {
std::vector<T*> cycle;
for (const auto& node : container) {
if (DetectCycle(&*node, &cycle)) {
throw CycleError("Detected a cycle in " + GetUniqueName(&*node) + " " +
std::string(type) + ":\n" + PrintCycle(cycle));
SCRAM_THROW(CycleError("Detected a cycle in " + GetUniqueName(&*node) +
" " + std::string(type) + ":\n" +
PrintCycle(cycle)));
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ Element::Element(std::string name) { Element::name(std::move(name)); }

void Element::name(std::string name) {
if (name.empty())
throw LogicError("The element name cannot be empty");
SCRAM_THROW(LogicError("The element name cannot be empty"));
if (name.find('.') != std::string::npos)
throw ValidityError("The element name is malformed.");
SCRAM_THROW(ValidityError("The element name is malformed."));
name_ = std::move(name);
}

void Element::AddAttribute(Attribute attr) {
if (HasAttribute(attr.name)) {
throw DuplicateArgumentError(
SCRAM_THROW(DuplicateArgumentError(
"Trying to overwrite an existing attribute {event: " + name_ +
", attr: " + attr.name + "} ");
", attr: " + attr.name + "} "));
}
attributes_.emplace_back(std::move(attr));
}
Expand Down Expand Up @@ -70,7 +70,7 @@ const Attribute& Element::GetAttribute(const std::string& name) const {
return attr.name == name;
});
if (it == attributes_.end())
throw LogicError("Element does not have attribute: " + name);
SCRAM_THROW(LogicError("Element does not have attribute: " + name));

return *it;
}
Expand All @@ -90,10 +90,10 @@ Role::Role(RoleSpecifier role, std::string base_path)
kRole_(role) {
if (!kBasePath_.empty() &&
(kBasePath_.front() == '.' || kBasePath_.back() == '.')) {
throw ValidityError("Element reference base path is malformed.");
SCRAM_THROW(ValidityError("Element reference base path is malformed."));
}
if (kRole_ == RoleSpecifier::kPrivate && kBasePath_.empty())
throw ValidityError("Elements cannot be private at model scope.");
SCRAM_THROW(ValidityError("Elements cannot be private at model scope."));
}

Id::Id(std::string name, std::string base_path, RoleSpecifier role)
Expand Down
40 changes: 21 additions & 19 deletions src/event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ void Gate::Validate() const {
return;
}
if (formula_->num_args() != 2) {
throw ValidityError(Element::name() +
"INHIBIT gate must have only 2 children");
SCRAM_THROW(ValidityError(Element::name() +
"INHIBIT gate must have only 2 children"));
}
int num_conditional = boost::count_if(
formula_->event_args(), [](const Formula::EventArg& event) {
Expand All @@ -63,29 +63,29 @@ void Gate::Validate() const {
basic_event->GetAttribute("flavor").value == "conditional";
});
if (num_conditional != 1)
throw ValidityError(Element::name() + " : INHIBIT gate must have" +
" exactly one conditional event.");
SCRAM_THROW(ValidityError(Element::name() + " : INHIBIT gate must have" +
" exactly one conditional event."));
}

Formula::Formula(Operator type) : type_(type), vote_number_(0) {}

int Formula::vote_number() const {
if (!vote_number_)
throw LogicError("Vote number is not set.");
SCRAM_THROW(LogicError("Vote number is not set."));
return vote_number_;
}

void Formula::vote_number(int number) {
if (type_ != kVote) {
throw LogicError(
SCRAM_THROW(LogicError(
"The vote number can only be defined for 'atleast' formulas. "
"The operator of this formula is '" +
std::string(kOperatorToString[type_]) + "'.");
std::string(kOperatorToString[type_]) + "'."));
}
if (number < 2)
throw ValidityError("Vote number cannot be less than 2.");
SCRAM_THROW(ValidityError("Vote number cannot be less than 2."));
if (vote_number_)
throw LogicError("Trying to re-assign a vote number");
SCRAM_THROW(LogicError("Trying to re-assign a vote number"));

vote_number_ = number;
}
Expand All @@ -95,7 +95,7 @@ void Formula::AddArgument(EventArg event_arg) {
if (ext::any_of(event_args_, [&event](const EventArg& arg) {
return ext::as<Event*>(arg)->id() == event->id();
})) {
throw DuplicateArgumentError("Duplicate argument " + event->name());
SCRAM_THROW(DuplicateArgumentError("Duplicate argument " + event->name()));
}
event_args_.push_back(event_arg);
if (!event->usage())
Expand All @@ -105,7 +105,7 @@ void Formula::AddArgument(EventArg event_arg) {
void Formula::RemoveArgument(EventArg event_arg) {
auto it = boost::find(event_args_, event_arg);
if (it == event_args_.end())
throw LogicError("The argument doesn't belong to this formula.");
SCRAM_THROW(LogicError("The argument doesn't belong to this formula."));
event_args_.erase(it);
}

Expand All @@ -116,24 +116,26 @@ void Formula::Validate() const {
case kNand:
case kNor:
if (num_args() < 2)
throw ValidityError("\"" + std::string(kOperatorToString[type_]) +
"\" formula must have 2 or more arguments.");
SCRAM_THROW(ValidityError("\"" + std::string(kOperatorToString[type_]) +
"\" formula must have 2 or more arguments."));
break;
case kNot:
case kNull:
if (num_args() != 1)
throw ValidityError("\"" + std::string(kOperatorToString[type_]) +
"\" formula must have only one argument.");
SCRAM_THROW(ValidityError("\"" + std::string(kOperatorToString[type_]) +
"\" formula must have only one argument."));
break;
case kXor:
if (num_args() != 2)
throw ValidityError("\"xor\" formula must have exactly 2 arguments.");
SCRAM_THROW(
ValidityError("\"xor\" formula must have exactly 2 arguments."));
break;
case kVote:
if (num_args() <= vote_number_)
throw ValidityError("\"atleast\" formula must have more arguments "
"than its vote number " +
std::to_string(vote_number_) + ".");
SCRAM_THROW(
ValidityError("\"atleast\" formula must have more arguments "
"than its vote number " +
std::to_string(vote_number_) + "."));
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/event_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace mef {

Path::Path(std::string state) : state_(std::move(state)) {
if (state_.empty())
throw LogicError("The state string for functional events cannot be empty");
SCRAM_THROW(
LogicError("The state string for functional events cannot be empty"));
}

Fork::Fork(const FunctionalEvent& functional_event, std::vector<Path> paths)
Expand All @@ -42,8 +43,8 @@ Fork::Fork(const FunctionalEvent& functional_event, std::vector<Path> paths)
return fork_path.state() == it->state();
});
if (it_find != paths_.end())
throw ValidityError("Duplicate state '" + it->state() +
"' path in fork " + functional_event_.name());
SCRAM_THROW(ValidityError("Duplicate state '" + it->state() +
"' path in fork " + functional_event_.name()));
}
}

Expand Down
27 changes: 14 additions & 13 deletions src/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ class NaryExpression<T, -1> : public ExpressionFormula<NaryExpression<T, -1>> {
explicit NaryExpression(std::vector<Expression*> args)
: ExpressionFormula<NaryExpression<T, -1>>(std::move(args)) {
if (Expression::args().size() < 2)
throw ValidityError("Expression requires 2 or more arguments.");
SCRAM_THROW(ValidityError("Expression requires 2 or more arguments."));
}

void Validate() const override {}
Expand Down Expand Up @@ -287,12 +287,12 @@ inline void EnsureProbability(Expression* expression,
const char* type = "probability") {
double value = expression->value();
if (value < 0 || value > 1)
throw DomainError("Invalid " + std::string(type) + " value for " +
description);
SCRAM_THROW(DomainError("Invalid " + std::string(type) + " value for " +
description));

if (IsProbability(expression->interval()) == false)
throw DomainError("Invalid " + std::string(type) + " sample domain for " +
description);
SCRAM_THROW(DomainError("Invalid " + std::string(type) +
" sample domain for " + description));
}

/// Ensures that expression yields positive (> 0) values.
Expand All @@ -304,10 +304,10 @@ inline void EnsureProbability(Expression* expression,
inline void EnsurePositive(Expression* expression,
const std::string& description) {
if (expression->value() <= 0)
throw DomainError(description + " argument value must be positive.");
SCRAM_THROW(DomainError(description + " argument value must be positive."));
if (IsPositive(expression->interval()) == false)
throw DomainError(description +
" argument sample domain must be positive.");
SCRAM_THROW(
DomainError(description + " argument sample domain must be positive."));
}

/// Ensures that expression yields non-negative (>= 0) values.
Expand All @@ -319,10 +319,11 @@ inline void EnsurePositive(Expression* expression,
inline void EnsureNonNegative(Expression* expression,
const std::string& description) {
if (expression->value() < 0)
throw DomainError(description + " argument value cannot be negative.");
SCRAM_THROW(
DomainError(description + " argument value cannot be negative."));
if (IsNonNegative(expression->interval()) == false)
throw DomainError(description +
" argument sample cannot have negative values.");
SCRAM_THROW(DomainError(description +
" argument sample cannot have negative values."));
}

/// Ensures that expression values are within the interval.
Expand All @@ -339,14 +340,14 @@ inline void EnsureWithin(Expression* expression, const Interval& interval,
std::stringstream ss;
ss << type << " argument value [" << arg_value << "] must be in "
<< interval << ".";
throw DomainError(ss.str());
SCRAM_THROW(DomainError(ss.str()));
}
Interval arg_interval = expression->interval();
if (!boost::icl::within(arg_interval, interval)) {
std::stringstream ss;
ss << type << " argument sample domain " << arg_interval << " must be in "
<< interval << ".";
throw DomainError(ss.str());
SCRAM_THROW(DomainError(ss.str()));
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/expression/exponential.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,11 @@ void PeriodicTest::Complete::Validate() const {
EnsureProbability(&omega_, "failure at restart");

if (test_duration_.value() > tau_.value())
throw ValidityError(
"The test duration must be less than the time between tests.");
SCRAM_THROW(ValidityError(
"The test duration must be less than the time between tests."));
if (test_duration_.interval().upper() > tau_.interval().lower())
throw ValidityError(
"The sampled test duration must be less than the time between tests.");
SCRAM_THROW(ValidityError(
"The sampled test duration must be less than the time between tests."));
}

double PeriodicTest::InstantRepair::Compute(double lambda, double tau,
Expand Down
Loading

0 comments on commit 86632fa

Please sign in to comment.