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

yao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 99da659dbafa [SPARK-45681][UI] Clone a js version of 
UIUtils.errorMessageCell for consistent error rendering on UI
99da659dbafa is described below

commit 99da659dbafa5a66d3dc10495f1441a3570059b6
Author: Kent Yao <[email protected]>
AuthorDate: Mon Oct 30 21:30:49 2023 +0800

    [SPARK-45681][UI] Clone a js version of UIUtils.errorMessageCell for 
consistent error rendering on UI
    
    ### What changes were proposed in this pull request?
    
    The task table on the stage page has its own version of error rendering 
using js, which does not catch up with recent updates on the java side.
    
    In this PR, we cloned a js version of UIUtils.errorMessageCell to make them 
behave the same
    
    ### Why are the changes needed?
    
    UI improvement
    
    ### Does this PR introduce _any_ user-facing change?
    
    yes, errors in the task table on the stage page will be abbreviated to 
error class first
    
    ### How was this patch tested?
    
    locally verified
    
    #### before
    
    
![image](https://github.com/apache/spark/assets/8326978/bd757ced-50b5-426e-8be1-1d0a74a2fead)
    
    #### after
    
    
![image](https://github.com/apache/spark/assets/8326978/3812aff7-6051-4f3e-b296-3af013148a3b)
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    no
    
    Closes #43547 from yaooqinn/SPARK-45681.
    
    Authored-by: Kent Yao <[email protected]>
    Signed-off-by: Kent Yao <[email protected]>
---
 .../org/apache/spark/ui/static/stagepage.js        |  8 ++---
 .../resources/org/apache/spark/ui/static/utils.js  | 40 +++++++++++++++++++++-
 .../main/scala/org/apache/spark/ui/UIUtils.scala   |  3 ++
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/core/src/main/resources/org/apache/spark/ui/static/stagepage.js 
b/core/src/main/resources/org/apache/spark/ui/static/stagepage.js
index 4b6b7e219e1e..7e997f9bcf87 100644
--- a/core/src/main/resources/org/apache/spark/ui/static/stagepage.js
+++ b/core/src/main/resources/org/apache/spark/ui/static/stagepage.js
@@ -17,7 +17,7 @@
 
 /* global $, ConvertDurationString, Mustache, 
createRESTEndPointForExecutorsPage */
 /* global createTemplateURI, formatBytes, formatDate, formatDuration, 
formatLogsCells */
-/* global getStandAloneAppId, setDataTableDefaults, getBaseURI, uiRoot */
+/* global getStandAloneAppId, setDataTableDefaults, getBaseURI, uiRoot 
errorMessageCell */
 
 var shouldBlockUI = true;
 var taskThreadDumpEnabled = false;
@@ -1067,11 +1067,7 @@ $(document).ready(function () {
                 if (typeof msg === 'undefined') {
                   return "";
                 } else {
-                  var indexOfLineSeparator = msg.indexOf("\n");
-                  var formHead = indexOfLineSeparator > 0 ? msg.substring(0, 
indexOfLineSeparator) : (msg.length > 100 ? msg.substring(0, 100) : msg);
-                  var form = "<span 
onclick=\"this.parentNode.querySelector('.stacktrace-details').classList.toggle('collapsed')\"
 class=\"expand-details\">+details</span>";
-                  var formMsg = "<div class=\"stacktrace-details 
collapsed\"><pre>" + row.errorMessage + "</pre></div>";
-                  return formHead + form + formMsg;
+                  return errorMessageCell(msg)
                 }
               },
               name: "Errors"
diff --git a/core/src/main/resources/org/apache/spark/ui/static/utils.js 
b/core/src/main/resources/org/apache/spark/ui/static/utils.js
index 08701c86fa21..aa948e77b375 100644
--- a/core/src/main/resources/org/apache/spark/ui/static/utils.js
+++ b/core/src/main/resources/org/apache/spark/ui/static/utils.js
@@ -231,4 +231,42 @@ function createRESTEndPointForMiscellaneousProcess(appId) {
 function getBaseURI() {
   return document.baseURI || document.URL;
 }
-/* eslint-enable no-unused-vars */
\ No newline at end of file
+
+function detailsUINode(isMultiline, message) {
+  if (isMultiline) {
+    const span = '<span 
onclick="this.parentNode.querySelector(\'.stacktrace-details\').classList.toggle(\'collapsed\')"
 class="expand-details">+details</span>';
+    const pre = '<pre>' + message + '</pre>';
+    const div = '<div class="stacktrace-details collapsed">' + pre + '</div>';
+    return span + div;
+  } else {
+    return '';
+  }
+}
+
+const ERROR_CLASS_REGEX = /\[([A-Z][A-Z_.]+[A-Z])]/;
+
+/* This function works exactly the same as UIUtils.errorSummary, it shall be
+ * remained the same whichever changed */
+function errorSummary(errorMessage) {
+  let isMultiline = true;
+  const maybeErrorClass = errorMessage.match(ERROR_CLASS_REGEX);
+  let errorClassOrBrief;
+  if (maybeErrorClass.length === 2) {
+    errorClassOrBrief = maybeErrorClass[1];
+  } else if (errorMessage.indexOf('\n') >= 0) {
+    errorClassOrBrief = errorMessage.substring(0, errorMessage.indexOf('\n'));
+  } else if (errorMessage.indexOf(":") >= 0) {
+    errorClassOrBrief = errorMessage.substring(0, errorMessage.indexOf(":"));
+  } else {
+    isMultiline = false;
+    errorClassOrBrief = errorMessage;
+  }
+  return [errorClassOrBrief, isMultiline];
+}
+
+function errorMessageCell(errorMessage) {
+  const [summary, isMultiline] = errorSummary(errorMessage);
+  const details = detailsUINode(isMultiline, errorMessage);
+  return summary + details;
+}
+/* eslint-enable no-unused-vars */
diff --git a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala 
b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
index 4d3baabc495f..b725f0294661 100644
--- a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
+++ b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
@@ -708,6 +708,9 @@ private[spark] object UIUtils extends Logging {
 
   private final val ERROR_CLASS_REGEX = 
"""\[(?<errorClass>[A-Z][A-Z_.]+[A-Z])]""".r
 
+  /**
+   * This function works exactly the same as utils.errorSummary(javascript), 
it shall be
+   * remained the same whichever changed */
   def errorSummary(errorMessage: String): (String, Boolean) = {
     var isMultiline = true
     val maybeErrorClass =


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to