瀏覽代碼

[livy] Fix reporting spark exceptions

Erick Tryzelaar 10 年之前
父節點
當前提交
c9a5eccefd

+ 1 - 1
apps/spark/java/livy-repl/src/main/scala/com/cloudera/hue/livy/repl/Session.scala

@@ -17,7 +17,7 @@ object Session {
 }
 
 trait Session {
-  import com.cloudera.hue.livy.repl.Session._
+  import Session._
 
   def state: State
 

+ 2 - 4
apps/spark/java/livy-repl/src/main/scala/com/cloudera/hue/livy/repl/scala/SparkSession.scala

@@ -56,16 +56,14 @@ private class SparkSession extends Session {
             "status" -> "error",
             "execution_count" -> executeCount,
             "ename" -> "Error",
-            "evalue" -> "output",
-            "traceback" -> List()
+            "evalue" -> output
           )
         case ExecuteError(executeCount, output) =>
           Map(
             "status" -> "error",
             "execution_count" -> executeCount,
             "ename" -> "Error",
-            "evalue" -> "output",
-            "traceback" -> List()
+            "evalue" -> output
           )
       }
 

+ 37 - 0
apps/spark/java/livy-repl/src/test/scala/com/cloudera/hue/livy/repl/PythonSessionSpec.scala

@@ -1,6 +1,7 @@
 package com.cloudera.hue.livy.repl
 
 import com.cloudera.hue.livy.repl.python.PythonSession
+import org.json4s.JsonAST.JValue
 import org.json4s.{Extraction, DefaultFormats}
 import org.scalatest.{BeforeAndAfter, FunSpec}
 import org.scalatest.matchers.ShouldMatchers
@@ -110,5 +111,41 @@ class PythonSessionSpec extends FunSpec with ShouldMatchers with BeforeAndAfter
 
       result should equal (expectedResult)
     }
+
+    it("should report an error if accessing an unknown variable") {
+      val result = Await.result(session.execute("""x"""), Duration.Inf)
+      val expectedResult = Extraction.decompose(Map(
+        "status" -> "error",
+        "execution_count" -> 0,
+        "traceback" -> List(
+          "Traceback (most recent call last):\n",
+          "NameError: name 'x' is not defined\n"
+        ),
+        "ename" -> "NameError",
+        "evalue" -> "name 'x' is not defined"
+      ))
+
+      result should equal (expectedResult)
+    }
+
+    it("should report an error if exception is thrown") {
+      val result = Await.result(session.execute(
+        """def foo():
+          |    raise Exception()
+          |foo()
+          |""".stripMargin), Duration.Inf)
+      val expectedResult = Extraction.decompose(Map(
+        "status" -> "error",
+        "execution_count" -> 0,
+        "traceback" -> List(
+          "Traceback (most recent call last):\n",
+          "Exception\n"
+        ),
+        "ename" -> "Exception",
+        "evalue" -> ""
+      ))
+
+      result should equal (expectedResult)
+    }
   }
 }

+ 29 - 1
apps/spark/java/livy-repl/src/test/scala/com/cloudera/hue/livy/repl/SparkSessionSpec.scala

@@ -1,9 +1,10 @@
 package com.cloudera.hue.livy.repl
 
 import com.cloudera.hue.livy.repl.scala.SparkSession
+import org.json4s.JsonAST.JValue
 import org.json4s.{DefaultFormats, Extraction}
 import org.scalatest.matchers.ShouldMatchers
-import org.scalatest.{FunSpec, BeforeAndAfter}
+import org.scalatest.{BeforeAndAfter, FunSpec}
 
 import _root_.scala.concurrent.Await
 import _root_.scala.concurrent.duration.Duration
@@ -92,5 +93,32 @@ class SparkSessionSpec extends FunSpec with ShouldMatchers with BeforeAndAfter {
 
       result should equal (expectedResult)
     }
+
+    it("should report an error if accessing an unknown variable") {
+      val result = Await.result(session.execute("""x"""), Duration.Inf)
+      val expectedResult = Extraction.decompose(Map(
+        "status" -> "error",
+        "execution_count" -> 0,
+        "ename" -> "Error",
+        "evalue" ->
+          """<console>:8: error: not found: value x
+            |              x
+            |              ^""".stripMargin
+      ))
+
+      result should equal (expectedResult)
+    }
+
+    it("should report an error if exception is thrown") {
+      val result = Await.result(session.execute("""throw new Exception()"""), Duration.Inf)
+      val resultMap = result.extract[Map[String, JValue]]
+
+      // Manually extract the values since the line numbers in the exception could change.
+      resultMap("status").extract[String] should equal ("error")
+      resultMap("execution_count").extract[Int] should equal (0)
+      resultMap("ename").extract[String] should equal ("Error")
+      resultMap("evalue").extract[String] should include ("java.lang.Exception")
+      resultMap.get("traceback") should equal (None)
+    }
   }
  }