You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/08/24 07:56:08 UTC

(texera) 01/01: fix(visualization, v1.2): define the render_error the table charts already call (#7905)

This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/release/v1.2/pr-7905-0f3faa4c6247ce5c1c642a206413715f73a8a134
in repository https://gitbox.apache.org/repos/asf/texera.git

commit e49f3379f1a5eac75d7fbfbb54a14503f168da87
Author: Kary Zheng <15...@users.noreply.github.com>
AuthorDate: Mon Aug 24 07:55:46 2026 +0000

    fix(visualization, v1.2): define the render_error the table charts already call (#7905)
    
    ### What changes were proposed in this PR?
    
    Manual backport of #7260 to `release/v1.2`, replacing #7389, whose head
    branch lives in this repository and so could not be corrected by push.
    
    The production half of the automated backport was already right:
    `TablesPlotOpDesc` and `FigureFactoryTableOpDesc` each define the
    `render_error` their generated `TableChartOperator` calls on two
    reachable branches, three lines apiece, exactly as on `main`.
    
    The tests were what failed. Neither operator has a descriptor spec on
    this branch, so the automation resolved the missing files by taking
    `main`'s whole, 113 lines and 102 lines against the 11 apiece that #7260
    actually added. What came along asserts on behaviour that is not on this
    branch: `main` passes a message to each `assert`, this branch does not,
    so `intercept[AssertionError](...).getMessage` is null and six of the
    fourteen tests fail. Those messages arrived in later PRs that were not
    backported, and this one should not carry them.
    
    Each spec here holds the one case #7260 added and the scaffolding it
    needs to run.
    
    ### Any related issues, documentation, discussions?
    
    Backport of #7260. Originally linked #7244. Replaces #7389, which can be
    closed.
    
    ### How was this PR tested?
    
    `WorkflowOperator/scalafmtCheckAll` and the two descriptor specs on this
    branch, 2 tests, both passing. For the record, the automated resolution
    was run on this branch first and failed 6 of 14: two `cannot be empty`
    cases per spec, plus `at least 30` and `non-negative` in
    `FigureFactoryTableOpDescSpec`.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 5)
    
    Co-authored-by: Claude Opus 5 (1M context) <no...@anthropic.com>
    Co-authored-by: Xuan Gu <16...@users.noreply.github.com>
---
 .../FigureFactoryTableOpDesc.scala                 |  3 ++
 .../tablesChart/TablesPlotOpDesc.scala             |  3 ++
 .../FigureFactoryTableOpDescSpec.scala             | 53 ++++++++++++++++++++++
 .../tablesChart/TablesPlotOpDescSpec.scala         | 50 ++++++++++++++++++++
 4 files changed, 109 insertions(+)

diff --git a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDesc.scala b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDesc.scala
index 2b61652f96..edbb45236f 100644
--- a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDesc.scala
+++ b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDesc.scala
@@ -96,6 +96,9 @@ class FigureFactoryTableOpDesc extends PythonOperatorDescriptor {
        |
        |class TableChartOperator(UDFTableOperator):
        |
+       |    def render_error(self, error_msg) -> str:
+       |        return f"<h1>Figure Factory Table is not available.</h1><p>Reason is: {error_msg}</p>"
+       |
        |    def process_table(self, table: Table, port: int) -> Iterator[Optional[TableLike]]:
        |
        |        if table.empty:
diff --git a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDesc.scala b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDesc.scala
index 2ff29fdc0d..dd40832164 100644
--- a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDesc.scala
+++ b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDesc.scala
@@ -76,6 +76,9 @@ class TablesPlotOpDesc extends PythonOperatorDescriptor {
        |import plotly.io
        |class TableChartOperator(UDFTableOperator):
        |
+       |    def render_error(self, error_msg) -> str:
+       |        return f"<h1>Tables Plot is not available.</h1><p>Reason is: {error_msg}</p>"
+       |
        |    def process_table(self, table: Table, port: int) -> Iterator[Optional[TableLike]]:
        |
        |        if table.empty:
diff --git a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDescSpec.scala b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDescSpec.scala
new file mode 100644
index 0000000000..33247716ea
--- /dev/null
+++ b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/figureFactoryTable/FigureFactoryTableOpDescSpec.scala
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.texera.amber.operator.visualization.figureFactoryTable
+
+import org.scalatest.BeforeAndAfter
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+class FigureFactoryTableOpDescSpec extends AnyFlatSpec with BeforeAndAfter with Matchers {
+
+  var opDesc: FigureFactoryTableOpDesc = _
+
+  before {
+    opDesc = new FigureFactoryTableOpDesc()
+  }
+
+  private def column(name: String): FigureFactoryTableConfig = {
+    val config = new FigureFactoryTableConfig()
+    config.attributeName = name
+    config
+  }
+
+  private def withColumns(): Unit =
+    opDesc.columns = List(column("col_one"), column("col_two"))
+
+  it should "define the render_error the empty-table branches call" in {
+    // Both empty-table branches call self.render_error; without the definition they
+    // raised AttributeError instead of rendering the message.
+    withColumns()
+    val code = opDesc.generatePythonCode()
+    code should include("def render_error(self, error_msg) -> str:")
+    code should include(
+      """return f"<h1>Figure Factory Table is not available.</h1><p>Reason is: {error_msg}</p>""""
+    )
+  }
+}
diff --git a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDescSpec.scala b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDescSpec.scala
new file mode 100644
index 0000000000..53e0b36690
--- /dev/null
+++ b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/tablesChart/TablesPlotOpDescSpec.scala
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.texera.amber.operator.visualization.tablesChart
+
+import org.scalatest.BeforeAndAfter
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+class TablesPlotOpDescSpec extends AnyFlatSpec with BeforeAndAfter with Matchers {
+
+  var opDesc: TablesPlotOpDesc = _
+
+  before {
+    opDesc = new TablesPlotOpDesc()
+  }
+
+  private def column(name: String): TablesConfig = {
+    val config = new TablesConfig()
+    config.attributeName = name
+    config
+  }
+
+  it should "define the render_error the empty-table branches call" in {
+    // Both empty-table branches call self.render_error; without the definition they
+    // raised AttributeError instead of rendering the message.
+    opDesc.includedColumns = List(column("col_one"), column("col_two"))
+    val code = opDesc.generatePythonCode()
+    code should include("def render_error(self, error_msg) -> str:")
+    code should include(
+      """return f"<h1>Tables Plot is not available.</h1><p>Reason is: {error_msg}</p>""""
+    )
+  }
+}