now we use boost::format through our own front-end util::_Fmt solely, which both helps to reduce compilation time and code size, and gives us a direct string conversion, which automatically uses any custom operator string() available on arguments. While desirable as such, I did this conversion now, since it allows us to get rid of boost::str, which in turn helps to drill down any remaning uses of our own util::str
125 lines
3.6 KiB
C++
125 lines
3.6 KiB
C++
/*
|
|
HandlingPattern - A skeleton for executing commands, including standard implementations
|
|
|
|
Copyright (C) Lumiera.org
|
|
2008, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
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 2 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, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
* *****************************************************/
|
|
|
|
|
|
|
|
#include "lib/error.hpp"
|
|
#include "proc/control/handling-pattern.hpp"
|
|
#include "proc/control/handling-patterns.hpp"
|
|
#include "lib/format-string.hpp"
|
|
#include "lib/util.hpp"
|
|
|
|
|
|
using util::isnil;
|
|
using util::cStr;
|
|
using util::_Fmt;
|
|
|
|
|
|
namespace proc {
|
|
namespace control {
|
|
namespace error = lumiera::error;
|
|
|
|
/** retrieve pre-configured pattern */
|
|
HandlingPattern const&
|
|
HandlingPattern::get (ID id)
|
|
{
|
|
return getPatternInstance(id);
|
|
}
|
|
|
|
|
|
/** @param name to use in log and error messages
|
|
* @note does error handling, but delegates the actual
|
|
* execution to the protected (subclass) member */
|
|
ExecResult
|
|
HandlingPattern::invoke (CommandImpl& command, Symbol name) const
|
|
{
|
|
TRACE (proc_dbg, "invoking %s...", name.c());
|
|
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.");
|
|
try
|
|
{
|
|
Symbol errID_pre = lumiera_error();
|
|
if (errID_pre)
|
|
return ExecResult (error::Logic (err_pre % command, errID_pre));
|
|
|
|
// execute or undo it...
|
|
perform (command);
|
|
|
|
Symbol errID = lumiera_error();
|
|
if (errID)
|
|
return ExecResult (error::State (err_post % command, errID));
|
|
else
|
|
return ExecResult();
|
|
}
|
|
|
|
|
|
catch (lumiera::Error& problem)
|
|
{
|
|
Symbol errID = lumiera_error();
|
|
WARN (command, "Invocation of %s failed: %s", name.c(), problem.what());
|
|
TRACE (proc_dbg, "Error flag was: %s", errID.c());
|
|
return ExecResult (problem);
|
|
}
|
|
catch (std::exception& library_problem)
|
|
{
|
|
Symbol errID = lumiera_error();
|
|
WARN (command, "Invocation of %s failed: %s", name.c(), library_problem.what());
|
|
TRACE (proc_dbg, "Error flag was: %s", errID.c());
|
|
return ExecResult (error::External (library_problem));
|
|
}
|
|
catch (...)
|
|
{
|
|
Symbol errID = lumiera_error();
|
|
ERROR (command, "Invocation of %s failed with unknown exception; error flag is: %s", name.c(), errID.c());
|
|
throw error::Fatal (err_fatal % command, errID);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* ====== execution result state object ======= */
|
|
|
|
|
|
/** @note we just grab and retain the error message.
|
|
* @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_);
|
|
}
|
|
|
|
|
|
}} // namespace proc::control
|