Fix missing location information for included files

fixes #7927
This commit is contained in:
Gunnar Beutner 2014-12-10 15:06:09 +01:00
parent c1ac548a77
commit 2720333d6e
21 changed files with 115 additions and 128 deletions

View File

@ -23,11 +23,11 @@ mkclass_target(streamlogger.ti streamlogger.thpp)
mkclass_target(sysloglogger.ti sysloglogger.thpp) mkclass_target(sysloglogger.ti sysloglogger.thpp)
set(base_SOURCES set(base_SOURCES
application.cpp application-version.cpp application.thpp array.cpp configerror.cpp console.cpp context.cpp application.cpp application-version.cpp application.thpp array.cpp console.cpp context.cpp
convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp logger.cpp logger.thpp exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp logger.cpp logger.thpp
netstring.cpp networkstream.cpp object.cpp primitivetype.cpp process.cpp netstring.cpp networkstream.cpp object.cpp primitivetype.cpp process.cpp
ringbuffer.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptsignal.cpp ringbuffer.cpp scripterror.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptsignal.cpp
scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp

View File

@ -108,11 +108,3 @@ void icinga::ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbo
} }
} }
std::string icinga::to_string(const errinfo_debuginfo& e)
{
std::ostringstream msgbuf;
msgbuf << "Config location: " << e.value() << "\n";
ShowCodeFragment(msgbuf, e.value(), true);
return msgbuf.str();
}

View File

@ -49,11 +49,6 @@ I2_BASE_API DebugInfo DebugInfoRange(const DebugInfo& start, const DebugInfo& en
I2_BASE_API void ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbose); I2_BASE_API void ShowCodeFragment(std::ostream& out, const DebugInfo& di, bool verbose);
struct errinfo_debuginfo_;
typedef boost::error_info<struct errinfo_debuginfo_, DebugInfo> errinfo_debuginfo;
I2_BASE_API std::string to_string(const errinfo_debuginfo& e);
} }
#endif /* DEBUGINFO_H */ #endif /* DEBUGINFO_H */

View File

@ -22,7 +22,7 @@
#include "base/debug.hpp" #include "base/debug.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
using namespace icinga; using namespace icinga;
@ -103,9 +103,9 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
if (it->second == object) if (it->second == object)
return; return;
BOOST_THROW_EXCEPTION(ConfigError("An object with type '" + m_Name + "' and name '" + name + "' already exists (" + BOOST_THROW_EXCEPTION(ScriptError("An object with type '" + m_Name + "' and name '" + name + "' already exists (" +
Convert::ToString(it->second->GetDebugInfo()) + "), new declaration: " + Convert::ToString(object->GetDebugInfo())) Convert::ToString(it->second->GetDebugInfo()) + "), new declaration: " + Convert::ToString(object->GetDebugInfo()),
<< errinfo_debuginfo(object->GetDebugInfo())); object->GetDebugInfo()));
} }
m_ObjectMap[name] = object; m_ObjectMap[name] = object;

View File

@ -17,19 +17,29 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <sstream> #include <sstream>
using namespace icinga; using namespace icinga;
ConfigError::ConfigError(const String& message) ScriptError::ScriptError(const String& message)
: m_Message(message) : m_Message(message)
{ } { }
ConfigError::~ConfigError(void) throw() ScriptError::ScriptError(const String& message, const DebugInfo& di)
: m_Message(message), m_DebugInfo(di)
{ } { }
const char *ConfigError::what(void) const throw() ScriptError::~ScriptError(void) throw()
{ }
const char *ScriptError::what(void) const throw()
{ {
return m_Message.CStr(); return m_Message.CStr();
} }
DebugInfo ScriptError::GetDebugInfo(void) const
{
return m_DebugInfo;
}

View File

@ -17,8 +17,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef CONFIGERROR_H #ifndef SCRIPTERROR_H
#define CONFIGERROR_H #define SCRIPTERROR_H
#include "base/i2-base.hpp" #include "base/i2-base.hpp"
#include "base/debuginfo.hpp" #include "base/debuginfo.hpp"
@ -30,18 +30,22 @@ namespace icinga
/* /*
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API ConfigError : virtual public user_error class I2_BASE_API ScriptError : virtual public user_error
{ {
public: public:
ConfigError(const String& message); ScriptError(const String& message);
~ConfigError(void) throw(); ScriptError(const String& message, const DebugInfo& di);
~ScriptError(void) throw();
virtual const char *what(void) const throw(); virtual const char *what(void) const throw();
DebugInfo GetDebugInfo(void) const;
private: private:
String m_Message; String m_Message;
DebugInfo m_DebugInfo;
}; };
} }
#endif /* CONFIGERROR_H */ #endif /* SCRIPTERROR_H */

View File

@ -26,7 +26,7 @@
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
#include "base/application.hpp" #include "base/application.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <algorithm> #include <algorithm>
@ -256,6 +256,6 @@ DynamicObject::Ptr ScriptUtils::GetObject(const String& type, const String& name
void ScriptUtils::Assert(const Value& arg) void ScriptUtils::Assert(const Value& arg)
{ {
if (!arg.ToBool()) if (!arg.ToBool())
BOOST_THROW_EXCEPTION(ConfigError("Assertion failed")); BOOST_THROW_EXCEPTION(std::runtime_error("Assertion failed"));
} }

View File

@ -67,9 +67,8 @@ static void ExecuteExpression(Expression *expression)
try { try {
VMFrame frame; VMFrame frame;
expression->Evaluate(frame); expression->Evaluate(frame);
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex)); ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
} }

View File

@ -91,14 +91,12 @@ int ReplCommand::Run(const po::variables_map& vm, const std::vector<std::string>
std::cout << result; std::cout << result;
std::cout << ConsoleColorTag(Console_Normal) << "\n"; std::cout << ConsoleColorTag(Console_Normal) << "\n";
} }
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); DebugInfo di = ex.GetDebugInfo();
if (di) { std::cout << String(3 + di.FirstColumn, ' ');
std::cout << String(3 + di->FirstColumn, ' '); std::cout << String(di.LastColumn - di.FirstColumn + 1, '^');
std::cout << String(di->LastColumn - di->FirstColumn + 1, '^'); std::cout << "\n";
std::cout << "\n";
}
std::cout << ex.what() << "\n"; std::cout << ex.what() << "\n";
} catch (const std::exception& ex) { } catch (const std::exception& ex) {

View File

@ -84,7 +84,7 @@ do { \
} }
<STRING>\n { <STRING>\n {
BOOST_THROW_EXCEPTION(ConfigError("Unterminated string literal") << errinfo_debuginfo(*yylloc)); BOOST_THROW_EXCEPTION(ScriptError("Unterminated string literal", *yylloc));
} }
<STRING>\\[0-7]{1,3} { <STRING>\\[0-7]{1,3} {
@ -95,7 +95,7 @@ do { \
if (result > 0xff) { if (result > 0xff) {
/* error, constant is out-of-bounds */ /* error, constant is out-of-bounds */
BOOST_THROW_EXCEPTION(ConfigError("Constant is out of bounds: " + String(yytext)) << errinfo_debuginfo(*yylloc)); BOOST_THROW_EXCEPTION(ScriptError("Constant is out of bounds: " + String(yytext), *yylloc));
} }
yyextra->m_LexBuffer << static_cast<char>(result); yyextra->m_LexBuffer << static_cast<char>(result);
@ -105,7 +105,7 @@ do { \
/* generate error - bad escape sequence; something /* generate error - bad escape sequence; something
* like '\48' or '\0777777' * like '\48' or '\0777777'
*/ */
BOOST_THROW_EXCEPTION(ConfigError("Bad escape sequence found: " + String(yytext)) << errinfo_debuginfo(*yylloc)); BOOST_THROW_EXCEPTION(ScriptError("Bad escape sequence found: " + String(yytext), *yylloc));
} }
<STRING>\\n { yyextra->m_LexBuffer << "\n"; } <STRING>\\n { yyextra->m_LexBuffer << "\n"; }
@ -122,7 +122,7 @@ do { \
yyextra->m_LexBuffer << *yptr++; yyextra->m_LexBuffer << *yptr++;
} }
<STRING><<EOF>> { BOOST_THROW_EXCEPTION(ConfigError("End-of-file while in string literal") << errinfo_debuginfo(*yylloc)); } <STRING><<EOF>> { BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in string literal", *yylloc)); }
\{\{\{ { yyextra->m_LexBuffer.str(""); yyextra->m_LexBuffer.clear(); BEGIN(HEREDOC); } \{\{\{ { yyextra->m_LexBuffer.str(""); yyextra->m_LexBuffer.clear(); BEGIN(HEREDOC); }
@ -148,7 +148,7 @@ do { \
} }
<C_COMMENT><<EOF>> { <C_COMMENT><<EOF>> {
BOOST_THROW_EXCEPTION(ConfigError("End-of-file while in comment") << errinfo_debuginfo(*yylloc)); BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in comment", *yylloc));
} }

View File

@ -34,7 +34,7 @@
#include "base/scriptvariable.hpp" #include "base/scriptvariable.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <sstream> #include <sstream>
#include <stack> #include <stack>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -230,7 +230,7 @@ int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
void yyerror(YYLTYPE *locp, std::vector<Expression *> *, ConfigCompiler *, const char *err) void yyerror(YYLTYPE *locp, std::vector<Expression *> *, ConfigCompiler *, const char *err)
{ {
BOOST_THROW_EXCEPTION(ConfigError(err) << errinfo_debuginfo(*locp)); BOOST_THROW_EXCEPTION(ScriptError(err, *locp));
} }
int yyparse(std::vector<Expression *> *elist, ConfigCompiler *context); int yyparse(std::vector<Expression *> *elist, ConfigCompiler *context);
@ -465,7 +465,7 @@ object:
if (seen_assign) { if (seen_assign) {
if (!ObjectRule::IsValidSourceType(type)) if (!ObjectRule::IsValidSourceType(type))
BOOST_THROW_EXCEPTION(ConfigError("object rule 'assign' cannot be used for type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); BOOST_THROW_EXCEPTION(ScriptError("object rule 'assign' cannot be used for type '" + type + "'", DebugInfoRange(@2, @3)));
if (ignore) { if (ignore) {
Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5)); Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5));
@ -625,7 +625,7 @@ lterm: type
| T_ASSIGN T_WHERE rterm | T_ASSIGN T_WHERE rterm
{ {
if ((context->m_Apply.empty() || !context->m_Apply.top()) && (context->m_ObjectAssign.empty() || !context->m_ObjectAssign.top())) if ((context->m_Apply.empty() || !context->m_Apply.top()) && (context->m_ObjectAssign.empty() || !context->m_ObjectAssign.top()))
BOOST_THROW_EXCEPTION(ConfigError("'assign' keyword not valid in this context.")); BOOST_THROW_EXCEPTION(ScriptError("'assign' keyword not valid in this context.", DebugInfoRange(@1, @3)));
context->m_SeenAssign.top() = true; context->m_SeenAssign.top() = true;
@ -639,7 +639,7 @@ lterm: type
| T_IGNORE T_WHERE rterm | T_IGNORE T_WHERE rterm
{ {
if ((context->m_Apply.empty() || !context->m_Apply.top()) && (context->m_ObjectAssign.empty() || !context->m_ObjectAssign.top())) if ((context->m_Apply.empty() || !context->m_Apply.top()) && (context->m_ObjectAssign.empty() || !context->m_ObjectAssign.top()))
BOOST_THROW_EXCEPTION(ConfigError("'ignore' keyword not valid in this context.")); BOOST_THROW_EXCEPTION(ScriptError("'ignore' keyword not valid in this context.", DebugInfoRange(@1, @3)));
if (context->m_Ignore.top()) if (context->m_Ignore.top())
context->m_Ignore.top() = new LogicalOrExpression(context->m_Ignore.top(), $3, DebugInfoRange(@1, @3)); context->m_Ignore.top() = new LogicalOrExpression(context->m_Ignore.top(), $3, DebugInfoRange(@1, @3));
@ -962,7 +962,7 @@ apply:
free($6); free($6);
if (!ApplyRule::IsValidSourceType(type)) if (!ApplyRule::IsValidSourceType(type))
BOOST_THROW_EXCEPTION(ConfigError("'apply' cannot be used with type '" + type + "'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); BOOST_THROW_EXCEPTION(ScriptError("'apply' cannot be used with type '" + type + "'", DebugInfoRange(@2, @3)));
if (!ApplyRule::IsValidTargetType(type, target)) { if (!ApplyRule::IsValidTargetType(type, target)) {
if (target == "") { if (target == "") {
@ -980,9 +980,9 @@ apply:
typeNames += "'" + types[i] + "'"; typeNames += "'" + types[i] + "'";
} }
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type is ambiguous (can be one of " + typeNames + "): use 'to' to specify a type") << errinfo_debuginfo(DebugInfoRange(@2, @3))); BOOST_THROW_EXCEPTION(ScriptError("'apply' target type is ambiguous (can be one of " + typeNames + "): use 'to' to specify a type", DebugInfoRange(@2, @3)));
} else } else
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5))); BOOST_THROW_EXCEPTION(ScriptError("'apply' target type '" + target + "' is invalid", DebugInfoRange(@2, @5)));
} }
DictExpression *exprl = dynamic_cast<DictExpression *>($8); DictExpression *exprl = dynamic_cast<DictExpression *>($8);
@ -990,7 +990,7 @@ apply:
// assign && !ignore // assign && !ignore
if (!context->m_SeenAssign.top()) if (!context->m_SeenAssign.top())
BOOST_THROW_EXCEPTION(ConfigError("'apply' is missing 'assign'") << errinfo_debuginfo(DebugInfoRange(@2, @3))); BOOST_THROW_EXCEPTION(ScriptError("'apply' is missing 'assign'", DebugInfoRange(@2, @3)));
context->m_SeenAssign.pop(); context->m_SeenAssign.pop();

View File

@ -34,7 +34,7 @@
#include "base/netstring.hpp" #include "base/netstring.hpp"
#include "base/serializer.hpp" #include "base/serializer.hpp"
#include "base/json.hpp" #include "base/json.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -167,9 +167,8 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
VMFrame frame(dobj); VMFrame frame(dobj);
frame.Locals = m_Scope; frame.Locals = m_Scope;
m_Expression->Evaluate(frame, &debugHints); m_Expression->Evaluate(frame, &debugHints);
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex)); ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
} }
@ -229,9 +228,8 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
try { try {
ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils); ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils);
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex)); ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
} }

View File

@ -24,7 +24,7 @@
#include "base/json.hpp" #include "base/json.hpp"
#include "base/object.hpp" #include "base/object.hpp"
#include "base/logger.hpp" #include "base/logger.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/exception_ptr.hpp> #include <boost/exception_ptr.hpp>
#include <boost/exception/errinfo_nested_exception.hpp> #include <boost/exception/errinfo_nested_exception.hpp>
@ -47,13 +47,11 @@ Value Expression::Evaluate(VMFrame& frame, DebugHint *dhint) const
return DoEvaluate(frame, dhint); return DoEvaluate(frame, dhint);
} catch (const InterruptExecutionError&) { } catch (const InterruptExecutionError&) {
throw; throw;
} catch (const ScriptError& ex) {
throw;
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
if (boost::get_error_info<boost::errinfo_nested_exception>(ex)) BOOST_THROW_EXCEPTION(ScriptError("Error while evaluating expression: " + String(ex.what()), GetDebugInfo())
throw; << boost::errinfo_nested_exception(boost::current_exception()));
else
BOOST_THROW_EXCEPTION(ConfigError("Error while evaluating expression: " + String(ex.what()))
<< boost::errinfo_nested_exception(boost::current_exception())
<< errinfo_debuginfo(GetDebugInfo()));
} }
} }
@ -191,7 +189,7 @@ Value InExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
if (right.IsEmpty()) if (right.IsEmpty())
return false; return false;
else if (!right.IsObjectType<Array>()) else if (!right.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right))); BOOST_THROW_EXCEPTION(ScriptError("Invalid right side argument for 'in' operator: " + JsonEncode(right), GetDebugInfo()));
Value left = m_Operand1->Evaluate(frame); Value left = m_Operand1->Evaluate(frame);
@ -206,7 +204,7 @@ Value NotInExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
if (right.IsEmpty()) if (right.IsEmpty())
return true; return true;
else if (!right.IsObjectType<Array>()) else if (!right.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right))); BOOST_THROW_EXCEPTION(ScriptError("Invalid right side argument for 'in' operator: " + JsonEncode(right), GetDebugInfo()));
Value left = m_Operand1->Evaluate(frame); Value left = m_Operand1->Evaluate(frame);
@ -292,7 +290,7 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
object = indexExpr->Evaluate(frame, dhint); object = indexExpr->Evaluate(frame, dhint);
if (!object) if (!object)
BOOST_THROW_EXCEPTION(ConfigError("Left-hand side argument must not be null.")); BOOST_THROW_EXCEPTION(ScriptError("Left-hand side argument must not be null.", GetDebugInfo()));
continue; continue;
} }
@ -400,7 +398,7 @@ Value ImportExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
ConfigItem::Ptr item = ConfigItem::GetObject(type, name); ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
if (!item) if (!item)
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'")); BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", GetDebugInfo()));
item->GetExpression()->Evaluate(frame, dhint); item->GetExpression()->Evaluate(frame, dhint);

View File

@ -26,7 +26,7 @@
#include "base/array.hpp" #include "base/array.hpp"
#include "base/dictionary.hpp" #include "base/dictionary.hpp"
#include "base/scriptfunction.hpp" #include "base/scriptfunction.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/thread/future.hpp> #include <boost/thread/future.hpp>

View File

@ -31,7 +31,7 @@
#include "base/scriptfunction.hpp" #include "base/scriptfunction.hpp"
#include "base/scriptsignal.hpp" #include "base/scriptsignal.hpp"
#include "base/scriptvariable.hpp" #include "base/scriptvariable.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -67,7 +67,7 @@ public:
func = ScriptFunction::GetByName(funcName); func = ScriptFunction::GetByName(funcName);
if (!func) if (!func)
BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist.")); BOOST_THROW_EXCEPTION(ScriptError("Function '" + funcName + "' does not exist."));
return func->Invoke(arguments); return func->Invoke(arguments);
} }
@ -104,7 +104,7 @@ public:
ScriptSignal::Ptr sig = ScriptSignal::GetByName(signal); ScriptSignal::Ptr sig = ScriptSignal::GetByName(signal);
if (!sig) if (!sig)
BOOST_THROW_EXCEPTION(ConfigError("Signal '" + signal + "' does not exist.")); BOOST_THROW_EXCEPTION(ScriptError("Signal '" + signal + "' does not exist."));
sig->AddSlot(boost::bind(SlotWrapper, slot, _1)); sig->AddSlot(boost::bind(SlotWrapper, slot, _1));
@ -143,7 +143,7 @@ public:
if (oldItem) { if (oldItem) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo(); msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo();
BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(debugInfo)); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
} }
} }
@ -152,7 +152,7 @@ public:
if (name.FindFirstOf("!") != String::NPos) { if (name.FindFirstOf("!") != String::NPos) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'"; msgbuf << "Name for object '" << name << "' of type '" << type << "' is invalid: Object names may not contain '!'";
BOOST_THROW_EXCEPTION(ConfigError(msgbuf.str()) << errinfo_debuginfo(debugInfo)); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
} }
item->SetName(name); item->SetName(name);
@ -171,7 +171,7 @@ public:
{ {
if (value.IsObjectType<Array>()) { if (value.IsObjectType<Array>()) {
if (!fvvar.IsEmpty()) if (!fvvar.IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Cannot use dictionary iterator for array.") << errinfo_debuginfo(debugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Cannot use dictionary iterator for array.", debugInfo));
Array::Ptr arr = value; Array::Ptr arr = value;
@ -182,7 +182,7 @@ public:
} }
} else if (value.IsObjectType<Dictionary>()) { } else if (value.IsObjectType<Dictionary>()) {
if (fvvar.IsEmpty()) if (fvvar.IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(debugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Cannot use array iterator for dictionary.", debugInfo));
Dictionary::Ptr dict = value; Dictionary::Ptr dict = value;
@ -194,7 +194,7 @@ public:
} }
} }
else else
BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(debugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Invalid type in __for expression: " + value.GetTypeName(), debugInfo));
return Empty; return Empty;
} }
@ -242,7 +242,7 @@ public:
return context->GetField(fid); return context->GetField(fid);
} }
static inline void SetField(const Object::Ptr& context, const String& field, const Value& value) static inline void SetField(const Object::Ptr& context, const String& field, const Value& value, const DebugInfo& debugInfo = DebugInfo())
{ {
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context); Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
@ -264,19 +264,19 @@ public:
Type::Ptr type = context->GetReflectionType(); Type::Ptr type = context->GetReflectionType();
if (!type) if (!type)
BOOST_THROW_EXCEPTION(ConfigError("Cannot set field on object.")); BOOST_THROW_EXCEPTION(ScriptError("Cannot set field on object.", debugInfo));
int fid = type->GetFieldId(field); int fid = type->GetFieldId(field);
if (fid == -1) if (fid == -1)
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' does not exist.")); BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' does not exist.", debugInfo));
try { try {
context->SetField(fid, value); context->SetField(fid, value);
} catch (const boost::bad_lexical_cast&) { } catch (const boost::bad_lexical_cast&) {
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'")); BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'", debugInfo));
} catch (const std::bad_cast&) { } catch (const std::bad_cast&) {
BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'")); BOOST_THROW_EXCEPTION(ScriptError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'", debugInfo));
} }
} }
@ -285,7 +285,7 @@ private:
const std::vector<String>& funcargs, const Dictionary::Ptr& closedVars, const boost::shared_ptr<Expression>& expr) const std::vector<String>& funcargs, const Dictionary::Ptr& closedVars, const boost::shared_ptr<Expression>& expr)
{ {
if (arguments.size() < funcargs.size()) if (arguments.size() < funcargs.size())
BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function")); BOOST_THROW_EXCEPTION(std::invalid_argument("Too few arguments for function"));
VMFrame frame; VMFrame frame;
@ -315,7 +315,7 @@ private:
func = ScriptFunction::GetByName(funcName); func = ScriptFunction::GetByName(funcName);
if (!func) if (!func)
BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist.")); BOOST_THROW_EXCEPTION(ScriptError("Function '" + funcName + "' does not exist."));
func->Invoke(arguments); func->Invoke(arguments);
} }

View File

@ -27,7 +27,7 @@
#include "base/logger.hpp" #include "base/logger.hpp"
#include "base/context.hpp" #include "base/context.hpp"
#include "base/workqueue.hpp" #include "base/workqueue.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace icinga; using namespace icinga;
@ -109,7 +109,7 @@ bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyR
if (vinstances.IsObjectType<Array>()) { if (vinstances.IsObjectType<Array>()) {
if (!rule.GetFVVar().IsEmpty()) if (!rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
Array::Ptr arr = vinstances; Array::Ptr arr = vinstances;
@ -126,7 +126,7 @@ bool Dependency::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyR
} }
} else if (vinstances.IsObjectType<Dictionary>()) { } else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty()) if (rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
Dictionary::Ptr dict = vinstances; Dictionary::Ptr dict = vinstances;
@ -153,9 +153,8 @@ void Dependency::EvaluateApplyRules(const Host::Ptr& host)
try { try {
if (EvaluateApplyRule(host, rule)) if (EvaluateApplyRule(host, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }
@ -171,9 +170,8 @@ void Dependency::EvaluateApplyRules(const Service::Ptr& service)
try { try {
if (EvaluateApplyRule(service, rule)) if (EvaluateApplyRule(service, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }

View File

@ -23,7 +23,7 @@
#include "icinga/pluginutility.hpp" #include "icinga/pluginutility.hpp"
#include "icinga/scheduleddowntime.hpp" #include "icinga/scheduleddowntime.hpp"
#include "config/configcompilercontext.hpp" #include "config/configcompilercontext.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"

View File

@ -27,7 +27,7 @@
#include "base/logger.hpp" #include "base/logger.hpp"
#include "base/context.hpp" #include "base/context.hpp"
#include "base/workqueue.hpp" #include "base/workqueue.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace icinga; using namespace icinga;
@ -108,7 +108,7 @@ bool Notification::EvaluateApplyRule(const Checkable::Ptr& checkable, const Appl
if (vinstances.IsObjectType<Array>()) { if (vinstances.IsObjectType<Array>()) {
if (!rule.GetFVVar().IsEmpty()) if (!rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
Array::Ptr arr = vinstances; Array::Ptr arr = vinstances;
@ -125,7 +125,7 @@ bool Notification::EvaluateApplyRule(const Checkable::Ptr& checkable, const Appl
} }
} else if (vinstances.IsObjectType<Dictionary>()) { } else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty()) if (rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
Dictionary::Ptr dict = vinstances; Dictionary::Ptr dict = vinstances;
@ -153,9 +153,8 @@ void Notification::EvaluateApplyRules(const Host::Ptr& host)
try { try {
if (EvaluateApplyRule(host, rule)) if (EvaluateApplyRule(host, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }
@ -171,9 +170,8 @@ void Notification::EvaluateApplyRules(const Service::Ptr& service)
try { try {
if (EvaluateApplyRule(service, rule)) if (EvaluateApplyRule(service, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }

View File

@ -26,7 +26,7 @@
#include "base/dynamictype.hpp" #include "base/dynamictype.hpp"
#include "base/logger.hpp" #include "base/logger.hpp"
#include "base/context.hpp" #include "base/context.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace icinga; using namespace icinga;
@ -107,7 +107,7 @@ bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const
if (vinstances.IsObjectType<Array>()) { if (vinstances.IsObjectType<Array>()) {
if (!rule.GetFVVar().IsEmpty()) if (!rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
Array::Ptr arr = vinstances; Array::Ptr arr = vinstances;
@ -124,7 +124,7 @@ bool ScheduledDowntime::EvaluateApplyRule(const Checkable::Ptr& checkable, const
} }
} else if (vinstances.IsObjectType<Dictionary>()) { } else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty()) if (rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
Dictionary::Ptr dict = vinstances; Dictionary::Ptr dict = vinstances;
@ -151,9 +151,8 @@ void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host)
try { try {
if (EvaluateApplyRule(host, rule)) if (EvaluateApplyRule(host, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }
@ -169,9 +168,8 @@ void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service)
try { try {
if (EvaluateApplyRule(service, rule)) if (EvaluateApplyRule(service, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }

View File

@ -26,7 +26,7 @@
#include "base/logger.hpp" #include "base/logger.hpp"
#include "base/context.hpp" #include "base/context.hpp"
#include "base/workqueue.hpp" #include "base/workqueue.hpp"
#include "base/configerror.hpp" #include "base/scripterror.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
using namespace icinga; using namespace icinga;
@ -95,7 +95,7 @@ bool Service::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule)
if (vinstances.IsObjectType<Array>()) { if (vinstances.IsObjectType<Array>()) {
if (!rule.GetFVVar().IsEmpty()) if (!rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Array iterator requires value to be an array.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Array iterator requires value to be an array.", di));
Array::Ptr arr = vinstances; Array::Ptr arr = vinstances;
@ -112,7 +112,7 @@ bool Service::EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule)
} }
} else if (vinstances.IsObjectType<Dictionary>()) { } else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty()) if (rule.GetFVVar().IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Dictionary iterator requires value to be a dictionary.") << errinfo_debuginfo(di)); BOOST_THROW_EXCEPTION(ScriptError("Dictionary iterator requires value to be a dictionary.", di));
Dictionary::Ptr dict = vinstances; Dictionary::Ptr dict = vinstances;
@ -136,9 +136,8 @@ void Service::EvaluateApplyRules(const Host::Ptr& host)
try { try {
if (EvaluateApplyRule(host, rule)) if (EvaluateApplyRule(host, rule))
rule.AddMatch(); rule.AddMatch();
} catch (const ConfigError& ex) { } catch (const ScriptError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex); ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
} }
} }
} }

View File

@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(simple)
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "\"foo\" in \"bar\""); expr = ConfigCompiler::CompileText("<test>", "\"foo\" in \"bar\"");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError); BOOST_CHECK_THROW(expr->Evaluate(frame), ScriptError);
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in [ \"bar\", \"baz\" ]"); expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in [ \"bar\", \"baz\" ]");
@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(simple)
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in \"bar\""); expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in \"bar\"");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError); BOOST_CHECK_THROW(expr->Evaluate(frame), ScriptError);
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "{ a += 3 }"); expr = ConfigCompiler::CompileText("<test>", "{ a += 3 }");
@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(simple)
BOOST_CHECK(dict->Get("a") == 3); BOOST_CHECK(dict->Get("a") == 3);
expr = ConfigCompiler::CompileText("<test>", "test"); expr = ConfigCompiler::CompileText("<test>", "test");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError); BOOST_CHECK_THROW(expr->Evaluate(frame), ScriptError);
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "null + 3"); expr = ConfigCompiler::CompileText("<test>", "null + 3");
@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE(advanced)
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "__boost_test()"); expr = ConfigCompiler::CompileText("<test>", "__boost_test()");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError); BOOST_CHECK_THROW(expr->Evaluate(frame), ScriptError);
delete expr; delete expr;
Object::Ptr self = new Object(); Object::Ptr self = new Object();
@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(advanced)
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3"); expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
BOOST_CHECK_THROW(expr->Evaluate(frame), ConfigError); BOOST_CHECK_THROW(expr->Evaluate(frame), ScriptError);
expr = ConfigCompiler::CompileText("<test>", "__function() { 3 }()"); expr = ConfigCompiler::CompileText("<test>", "__function() { 3 }()");
BOOST_CHECK(expr->Evaluate(frame) == 3); BOOST_CHECK(expr->Evaluate(frame) == 3);