mirror of https://github.com/Icinga/icinga2.git
Merge pull request #5348 from Icinga/feature/try-except
Implement support for handling exceptions in user scripts
This commit is contained in:
commit
cc82e634c6
|
@ -851,7 +851,7 @@ Example:
|
||||||
|
|
||||||
var s = String(3) /* Sets s to "3". */
|
var s = String(3) /* Sets s to "3". */
|
||||||
|
|
||||||
## <a id="throw"></a> Exceptions
|
## <a id="throw"></a> Throwing Exceptions
|
||||||
|
|
||||||
Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions
|
Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions
|
||||||
using the `throw` keyword.
|
using the `throw` keyword.
|
||||||
|
@ -860,7 +860,20 @@ Example:
|
||||||
|
|
||||||
throw "An error occurred."
|
throw "An error occurred."
|
||||||
|
|
||||||
There is currently no way for scripts to catch exceptions.
|
## <a id="try-except"></a> Handling Exceptions
|
||||||
|
|
||||||
|
Exceptions can be handled using the `try` and `except` keywords. When an exception occurs while executing code in the
|
||||||
|
`try` clause no further statements in the `try` clause are evaluated and the `except` clause is executed instead.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
try {
|
||||||
|
throw "Test"
|
||||||
|
|
||||||
|
log("This statement won't get executed.")
|
||||||
|
} except {
|
||||||
|
log("An error occurred in the try clause.")
|
||||||
|
}
|
||||||
|
|
||||||
## <a id="breakpoints"></a> Breakpoints
|
## <a id="breakpoints"></a> Breakpoints
|
||||||
|
|
||||||
|
@ -920,7 +933,7 @@ These keywords are reserved and must not be used as constants or custom attribut
|
||||||
template
|
template
|
||||||
include
|
include
|
||||||
include_recursive
|
include_recursive
|
||||||
ignore_on_error
|
include_zones
|
||||||
library
|
library
|
||||||
null
|
null
|
||||||
true
|
true
|
||||||
|
@ -928,7 +941,13 @@ These keywords are reserved and must not be used as constants or custom attribut
|
||||||
const
|
const
|
||||||
var
|
var
|
||||||
this
|
this
|
||||||
|
globals
|
||||||
|
locals
|
||||||
use
|
use
|
||||||
|
default
|
||||||
|
ignore_on_error
|
||||||
|
current_filename
|
||||||
|
current_line
|
||||||
apply
|
apply
|
||||||
to
|
to
|
||||||
where
|
where
|
||||||
|
@ -937,12 +956,16 @@ These keywords are reserved and must not be used as constants or custom attribut
|
||||||
ignore
|
ignore
|
||||||
function
|
function
|
||||||
return
|
return
|
||||||
|
break
|
||||||
|
continue
|
||||||
for
|
for
|
||||||
if
|
if
|
||||||
else
|
else
|
||||||
|
while
|
||||||
|
throw
|
||||||
|
try
|
||||||
|
except
|
||||||
in
|
in
|
||||||
current_filename
|
|
||||||
current_line
|
|
||||||
|
|
||||||
You can escape reserved keywords using the `@` character. The following example
|
You can escape reserved keywords using the `@` character. The following example
|
||||||
tries to set `vars.include` which references a reserved keyword and generates
|
tries to set `vars.include` which references a reserved keyword and generates
|
||||||
|
|
|
@ -262,6 +262,8 @@ const std::vector<String>& ConfigWriter::GetKeywords(void)
|
||||||
keywords.push_back("else");
|
keywords.push_back("else");
|
||||||
keywords.push_back("while");
|
keywords.push_back("while");
|
||||||
keywords.push_back("throw");
|
keywords.push_back("throw");
|
||||||
|
keywords.push_back("try");
|
||||||
|
keywords.push_back("except");
|
||||||
}
|
}
|
||||||
|
|
||||||
return keywords;
|
return keywords;
|
||||||
|
|
|
@ -197,6 +197,8 @@ if return T_IF;
|
||||||
else return T_ELSE;
|
else return T_ELSE;
|
||||||
while return T_WHILE;
|
while return T_WHILE;
|
||||||
throw return T_THROW;
|
throw return T_THROW;
|
||||||
|
try return T_TRY;
|
||||||
|
except return T_EXCEPT;
|
||||||
ignore_on_error return T_IGNORE_ON_ERROR;
|
ignore_on_error return T_IGNORE_ON_ERROR;
|
||||||
current_filename return T_CURRENT_FILENAME;
|
current_filename return T_CURRENT_FILENAME;
|
||||||
current_line return T_CURRENT_LINE;
|
current_line return T_CURRENT_LINE;
|
||||||
|
|
|
@ -172,6 +172,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
||||||
%token T_ELSE "else (T_ELSE)"
|
%token T_ELSE "else (T_ELSE)"
|
||||||
%token T_WHILE "while (T_WHILE)"
|
%token T_WHILE "while (T_WHILE)"
|
||||||
%token T_THROW "throw (T_THROW)"
|
%token T_THROW "throw (T_THROW)"
|
||||||
|
%token T_TRY "try (T_TRY)"
|
||||||
|
%token T_EXCEPT "except (T_EXCEPT)"
|
||||||
%token T_FOLLOWS "=> (T_FOLLOWS)"
|
%token T_FOLLOWS "=> (T_FOLLOWS)"
|
||||||
%token T_NULLARY_LAMBDA_BEGIN "{{ (T_NULLARY_LAMBDA_BEGIN)"
|
%token T_NULLARY_LAMBDA_BEGIN "{{ (T_NULLARY_LAMBDA_BEGIN)"
|
||||||
%token T_NULLARY_LAMBDA_END "}} (T_NULLARY_LAMBDA_END)"
|
%token T_NULLARY_LAMBDA_END "}} (T_NULLARY_LAMBDA_END)"
|
||||||
|
@ -666,6 +668,10 @@ lterm: T_LIBRARY rterm
|
||||||
{
|
{
|
||||||
$$ = new ThrowExpression($2, false, @$);
|
$$ = new ThrowExpression($2, false, @$);
|
||||||
}
|
}
|
||||||
|
| T_TRY rterm_scope T_EXCEPT rterm_scope
|
||||||
|
{
|
||||||
|
$$ = new TryExceptExpression($2, $4, @$);
|
||||||
|
}
|
||||||
| rterm_side_effect
|
| rterm_side_effect
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -941,3 +941,16 @@ ExpressionResult UsingExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhin
|
||||||
return Empty;
|
return Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpressionResult TryExceptExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ExpressionResult tryResult = m_TryBody->Evaluate(frame, dhint);
|
||||||
|
CHECK_RESULT(tryResult);
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
ExpressionResult exceptResult = m_ExceptBody->Evaluate(frame, dhint);
|
||||||
|
CHECK_RESULT(exceptResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1027,6 +1027,27 @@ private:
|
||||||
Expression *m_Name;
|
Expression *m_Name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class I2_CONFIG_API TryExceptExpression : public DebuggableExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TryExceptExpression(Expression *tryBody, Expression *exceptBody, const DebugInfo& debugInfo = DebugInfo())
|
||||||
|
: DebuggableExpression(debugInfo), m_TryBody(tryBody), m_ExceptBody(exceptBody)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~TryExceptExpression(void)
|
||||||
|
{
|
||||||
|
delete m_TryBody;
|
||||||
|
delete m_ExceptBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expression *m_TryBody;
|
||||||
|
Expression *m_ExceptBody;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EXPRESSION_H */
|
#endif /* EXPRESSION_H */
|
||||||
|
|
Loading…
Reference in New Issue