fixed exception handling for failed dependency checks

master
Phanes 2017-12-03 21:15:41 -05:00
parent 5f85185e8d
commit 624e3a4a9c
3 changed files with 56 additions and 10 deletions

View File

@ -23,7 +23,12 @@ int main( )
std::cout << "Ready to execute all tasks in Plan." << std::endl; std::cout << "Ready to execute all tasks in Plan." << std::endl;
try {
plan.execute( verbose ); plan.execute( verbose );
}
catch ( std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0; return 0;
} }

View File

@ -14,10 +14,46 @@ class Plan_InvalidTaskName: public std::runtime_error { public:
/// Plan_Task_Missing_Dependency - Exception thrown when a Plan tries to access a contained Task's value by name not present /// Plan_Task_Missing_Dependency - Exception thrown when a Plan tries to access a contained Task's value by name not present
/// in the Unit. /// in the Unit.
class Plan_Task_Missing_Dependency: public std::runtime_error { public: class Plan_Task_Missing_Dependency: public std::exception
Plan_Task_Missing_Dependency(): std::runtime_error("Plan: Attempted to execute a task that had unmet dependencies.") {} {
}; public:
/** Constructor (C strings).
* @param message C-style string error message.
* The string contents are copied upon construction.
* Hence, responsibility for deleting the char* lies
* with the caller.
*/
explicit Plan_Task_Missing_Dependency(const char* message):
msg_(message)
{
}
/** Constructor (C++ STL strings).
* @param message The error message.
*/
explicit Plan_Task_Missing_Dependency(const std::string& message):
msg_(message)
{}
/** Destructor.
* Virtual to allow for subclassing.
*/
virtual ~Plan_Task_Missing_Dependency() throw (){}
/** Returns a pointer to the (constant) error description.
* @return A pointer to a const char*. The underlying memory
* is in posession of the Exception object. Callers must
* not attempt to free the memory.
*/
virtual const char* what() const throw (){
return msg_.c_str();
}
protected:
/** Error message.
*/
std::string msg_;
};
/// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference /// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference
/// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those /// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those
@ -165,8 +201,8 @@ void Plan::execute( bool verbose )
} }
this->tasks[i].execute( verbose ); this->tasks[i].execute( verbose );
} else { } else {
throw Plan_Task_Missing_Dependency();
// not all deps met for this task // not all deps met for this task
throw Plan_Task_Missing_Dependency( "Task \"" + this->tasks[i].get_name() + "\" was specified in the Plan but not executed due to missing dependencies. Please revise your plan." );
} }
} }
} }

View File

@ -21,7 +21,8 @@ public:
Task_RequiredButFailedTask(): std::runtime_error("Task: Attempted to execute a Task that failed and was required.") {} Task_RequiredButFailedTask(): std::runtime_error("Task: Attempted to execute a Task that failed and was required.") {}
}; };
/// Task_RequiredButFailedTask - Exception thrown when a Task is failed but required, and rectification also failed but returned with a zero exit code (dont try to fool the check). /// Task_RequiredButFailedTask - Exception thrown when a Task is failed but required, and rectification also failed but
/// returned with a zero exit code (dont try to fool the check).
class Task_RequiredButRectifierDoesNotHeal: public std::runtime_error { class Task_RequiredButRectifierDoesNotHeal: public std::runtime_error {
public: public:
Task_RequiredButRectifierDoesNotHeal(): std::runtime_error("Task: The rectification script was executed and reported success, but did not actually heal the faulty condition of the Task target.") {} Task_RequiredButRectifierDoesNotHeal(): std::runtime_error("Task: The rectification script was executed and reported success, but did not actually heal the faulty condition of the Task target.") {}
@ -60,7 +61,8 @@ void Task::load_root(Json::Value loader_root, bool verbose )
if ( des_dep_root[i].asString() != "" ) { if ( des_dep_root[i].asString() != "" ) {
this->dependencies.push_back( des_dep_root[i].asString() ); this->dependencies.push_back( des_dep_root[i].asString() );
if ( verbose ) { if ( verbose ) {
std::cout << "Added dependency \"" << des_dep_root[i].asString() << "\" to task \"" << this->get_name() << "\"." << std::endl; std::cout << "Added dependency \"" << des_dep_root[i].asString()
<< "\" to task \"" << this->get_name() << "\"." << std::endl;
} }
} }
} }
@ -80,7 +82,8 @@ void Task::load_definition( Unit selected_unit, bool verbose )
{ {
this->definition = selected_unit; this->definition = selected_unit;
if ( verbose ) { if ( verbose ) {
std::cout << "Loaded definition \"" << selected_unit.get_name() << "\" for task \"" << this->get_name() << "\"." << std::endl; std::cout << "Loaded definition \"" << selected_unit.get_name() << "\" for task \""
<< this->get_name() << "\"." << std::endl;
} }
this->defined = true; this->defined = true;
} }
@ -166,7 +169,9 @@ void Task::execute( bool verbose )
if (rectifier_error) { if (rectifier_error) {
//d[3] non-zero //d[3] non-zero
std::cout << "\tRectification of \"" << task_name << "\" failed with exit code " << rectifier_error << "." << std::endl; std::cout << "\tRectification of \"" << task_name << "\" failed with exit code "
<< rectifier_error << "." << std::endl;
// d[2] check if REQUIRED // d[2] check if REQUIRED
if ( this->definition.get_required() ) { if ( this->definition.get_required() ) {
// d[2] yes // d[2] yes