Browse Source

fix: except can now raise new errors / signals

Matthias Ladkau 3 years ago
parent
commit
1550304c4c
3 changed files with 54 additions and 7 deletions
  1. 8 7
      interpreter/rt_statements.go
  2. 44 0
      interpreter/rt_statements_test.go
  3. 2 0
      parser/parser_statement_test.go

+ 8 - 7
interpreter/rt_statements.go

@@ -561,8 +561,8 @@ func (rt *tryRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint6
 
 			for i := 1; i < len(rt.node.Children); i++ {
 				if child := rt.node.Children[i]; child.Name == parser.NodeEXCEPT {
-					if rt.evalExcept(vs, is, tid, errObj, child) {
-						err = nil
+					if ok, newerror := rt.evalExcept(vs, is, tid, errObj, child); ok {
+						err = newerror
 						break
 					}
 				}
@@ -574,7 +574,8 @@ func (rt *tryRuntime) Eval(vs parser.Scope, is map[string]interface{}, tid uint6
 }
 
 func (rt *tryRuntime) evalExcept(vs parser.Scope, is map[string]interface{},
-	tid uint64, errObj map[interface{}]interface{}, except *parser.ASTNode) bool {
+	tid uint64, errObj map[interface{}]interface{}, except *parser.ASTNode) (bool, error) {
+	var newerror error
 	ret := false
 
 	if len(except.Children) == 1 {
@@ -583,7 +584,7 @@ func (rt *tryRuntime) evalExcept(vs parser.Scope, is map[string]interface{},
 
 		evs := vs.NewChild(scope.NameFromASTNode(except))
 
-		except.Children[0].Runtime.Eval(evs, is, tid)
+		_, newerror = except.Children[0].Runtime.Eval(evs, is, tid)
 
 		ret = true
 
@@ -594,7 +595,7 @@ func (rt *tryRuntime) evalExcept(vs parser.Scope, is map[string]interface{},
 		evs := vs.NewChild(scope.NameFromASTNode(except))
 		evs.SetValue(except.Children[0].Token.Val, errObj)
 
-		except.Children[1].Runtime.Eval(evs, is, tid)
+		_, newerror = except.Children[1].Runtime.Eval(evs, is, tid)
 
 		ret = true
 
@@ -623,12 +624,12 @@ func (rt *tryRuntime) evalExcept(vs parser.Scope, is map[string]interface{},
 					evs.SetValue(errorVar, errObj)
 				}
 
-				child.Runtime.Eval(evs, is, tid)
+				_, newerror = child.Runtime.Eval(evs, is, tid)
 			}
 		}
 	}
 
-	return ret
+	return ret, newerror
 }
 
 // Mutex Runtime

+ 44 - 0
interpreter/rt_statements_test.go

@@ -1053,6 +1053,50 @@ error: This did not work`[1:] {
 		t.Error("Unexpected result:", testlogger.String())
 		return
 	}
+
+	_, err = UnitTestEval(
+		`
+try {
+	try {
+		x := 1 + "a"
+	} except e {
+		raise("usererror", "This did not work", e)
+	}
+} except e {
+	error(e)
+}
+`, vs)
+
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	if testlogger.String() != `
+error: {
+  "data": {
+    "detail": "a",
+    "error": "ECAL error in ECALTestRuntime: Operand is not a number (a) (Line:4 Pos:12)",
+    "line": 4,
+    "pos": 12,
+    "source": "ECALTestRuntime",
+    "trace": [],
+    "type": "Operand is not a number"
+  },
+  "detail": "This did not work",
+  "error": "ECAL error in ECALTestRuntime: usererror (This did not work) (Line:6 Pos:3)",
+  "line": 6,
+  "pos": 3,
+  "source": "ECALTestRuntime",
+  "trace": [
+    "raise(\"usererror\", \"This did not work\", e) (ECALEvalTest:6)"
+  ],
+  "type": "usererror"
+}`[1:] {
+		t.Error("Unexpected result:", testlogger.String())
+		return
+	}
+
 }
 
 func TestMutexStatements(t *testing.T) {

+ 2 - 0
parser/parser_statement_test.go

@@ -131,6 +131,8 @@ try
 	input = `
 try {
 	raise("test", [1,2,3])
+} else {
+	
 } finally {
 }
 `