2009-06-08 04:46:07 +02:00
|
|
|
/*
|
|
|
|
|
HandlingPattern - A skeleton for executing commands, including standard implementations
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2008, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
2010-12-17 23:28:49 +01:00
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
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.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
* *****************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-01-04 01:38:04 +01:00
|
|
|
#include "lib/error.hpp"
|
2009-08-09 21:55:47 +02:00
|
|
|
#include "proc/control/handling-pattern.hpp"
|
|
|
|
|
#include "proc/control/handling-patterns.hpp"
|
2016-01-04 01:38:04 +01:00
|
|
|
#include "lib/format-string.hpp"
|
2009-08-02 18:00:03 +02:00
|
|
|
#include "lib/util.hpp"
|
2009-06-08 04:46:07 +02:00
|
|
|
|
2009-08-02 18:00:03 +02:00
|
|
|
|
|
|
|
|
using util::isnil;
|
2009-10-02 15:26:11 +02:00
|
|
|
using util::cStr;
|
2016-01-04 01:38:04 +01:00
|
|
|
using util::_Fmt;
|
2009-08-02 18:00:03 +02:00
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
|
2011-12-02 17:50:44 +01:00
|
|
|
namespace proc {
|
2009-06-08 04:46:07 +02:00
|
|
|
namespace control {
|
2011-12-02 17:50:44 +01:00
|
|
|
namespace error = lumiera::error;
|
2009-06-08 04:46:07 +02:00
|
|
|
|
2009-10-01 13:29:53 +02:00
|
|
|
/** retrieve pre-configured pattern */
|
2009-07-26 02:00:47 +02:00
|
|
|
HandlingPattern const&
|
|
|
|
|
HandlingPattern::get (ID id)
|
|
|
|
|
{
|
2009-08-09 21:55:47 +02:00
|
|
|
return getPatternInstance(id);
|
2009-07-26 02:00:47 +02:00
|
|
|
}
|
2009-06-08 04:46:07 +02:00
|
|
|
|
2009-10-01 13:29:53 +02:00
|
|
|
|
2009-10-02 15:26:11 +02:00
|
|
|
/** @param name to use in log and error messages
|
|
|
|
|
* @note does error handling, but delegates the actual
|
2009-08-02 18:00:03 +02:00
|
|
|
* execution to the protected (subclass) member */
|
|
|
|
|
ExecResult
|
2009-09-21 03:11:46 +02:00
|
|
|
HandlingPattern::invoke (CommandImpl& command, Symbol name) const
|
2009-08-02 18:00:03 +02:00
|
|
|
{
|
2009-09-24 23:02:40 +02:00
|
|
|
TRACE (proc_dbg, "invoking %s...", name.c());
|
2016-01-04 01:38:04 +01:00
|
|
|
static _Fmt err_pre ("Error state detected, %s *NOT* invoked.");
|
|
|
|
|
static _Fmt err_post ("Error state after %s invocation.");
|
|
|
|
|
static _Fmt err_fatal ("Execution of %s raised unknown error.");
|
2009-08-02 18:00:03 +02:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Symbol errID_pre = lumiera_error();
|
|
|
|
|
if (errID_pre)
|
2016-01-04 01:38:04 +01:00
|
|
|
return ExecResult (error::Logic (err_pre % command, errID_pre));
|
2009-08-02 18:00:03 +02:00
|
|
|
|
2009-10-01 13:29:53 +02:00
|
|
|
// execute or undo it...
|
|
|
|
|
perform (command);
|
2009-08-02 18:00:03 +02:00
|
|
|
|
|
|
|
|
Symbol errID = lumiera_error();
|
|
|
|
|
if (errID)
|
2016-01-04 01:38:04 +01:00
|
|
|
return ExecResult (error::State (err_post % command, errID));
|
2009-08-02 18:00:03 +02:00
|
|
|
else
|
|
|
|
|
return ExecResult();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
catch (lumiera::Error& problem)
|
|
|
|
|
{
|
|
|
|
|
Symbol errID = lumiera_error();
|
2009-09-24 23:02:40 +02:00
|
|
|
WARN (command, "Invocation of %s failed: %s", name.c(), problem.what());
|
|
|
|
|
TRACE (proc_dbg, "Error flag was: %s", errID.c());
|
2009-08-02 18:00:03 +02:00
|
|
|
return ExecResult (problem);
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception& library_problem)
|
|
|
|
|
{
|
|
|
|
|
Symbol errID = lumiera_error();
|
2009-09-24 23:02:40 +02:00
|
|
|
WARN (command, "Invocation of %s failed: %s", name.c(), library_problem.what());
|
|
|
|
|
TRACE (proc_dbg, "Error flag was: %s", errID.c());
|
2009-08-02 18:00:03 +02:00
|
|
|
return ExecResult (error::External (library_problem));
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
Symbol errID = lumiera_error();
|
2009-09-24 23:02:40 +02:00
|
|
|
ERROR (command, "Invocation of %s failed with unknown exception; error flag is: %s", name.c(), errID.c());
|
2016-01-04 01:38:04 +01:00
|
|
|
throw error::Fatal (err_fatal % command, errID);
|
2009-08-02 18:00:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-06-08 04:46:07 +02:00
|
|
|
|
2009-08-02 18:00:03 +02:00
|
|
|
/* ====== execution result state object ======= */
|
|
|
|
|
|
|
|
|
|
|
2009-09-21 03:11:46 +02:00
|
|
|
/** @note we just grab and retain the error message.
|
2009-08-02 18:00:03 +02:00
|
|
|
* @todo rather keep the exception object around. */
|
|
|
|
|
ExecResult::ExecResult (lumiera::Error const& problem)
|
|
|
|
|
: log_(problem.what())
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
ExecResult::isValid() const
|
|
|
|
|
{
|
|
|
|
|
return isnil(log_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ExecResult::maybeThrow() const
|
|
|
|
|
{
|
|
|
|
|
if (!isnil (log_))
|
|
|
|
|
throw error::Logic ("Command execution failed: "+log_);
|
|
|
|
|
}
|
2009-10-01 13:29:53 +02:00
|
|
|
|
2009-08-02 18:00:03 +02:00
|
|
|
|
2011-12-02 17:50:44 +01:00
|
|
|
}} // namespace proc::control
|