IGNITE-8999 Web Console: Added support for optional "trace" in error message.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c8b3ba49
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c8b3ba49
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c8b3ba49

Branch: refs/heads/ignite-6467-1
Commit: c8b3ba49676949db15f15f19a24ca0ec3e41da08
Parents: 3e44ba2
Author: Vasiliy Sisko <vsi...@gridgain.com>
Authored: Mon Jul 30 17:42:32 2018 +0700
Committer: Alexey Kuznetsov <akuznet...@apache.org>
Committed: Mon Jul 30 17:42:32 2018 +0700

----------------------------------------------------------------------
 modules/web-console/frontend/app/app.js         |  2 +
 .../components/queries-notebook/controller.js   | 18 ++--
 .../app/services/ErrorParser.service.js         | 89 ++++++++++++++++++++
 .../frontend/app/services/Messages.service.js   | 29 +------
 4 files changed, 101 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c8b3ba49/modules/web-console/frontend/app/app.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.js 
b/modules/web-console/frontend/app/app.js
index 276eac8..b9d72ab 100644
--- a/modules/web-console/frontend/app/app.js
+++ b/modules/web-console/frontend/app/app.js
@@ -86,6 +86,7 @@ import SqlTypes from './services/SqlTypes.service';
 import LegacyTable from './services/LegacyTable.service';
 import LegacyUtils from './services/LegacyUtils.service';
 import Messages from './services/Messages.service';
+import ErrorParser from './services/ErrorParser.service';
 import ModelNormalizer from './services/ModelNormalizer.service.js';
 import UnsavedChangesGuard from './services/UnsavedChangesGuard.service';
 import Caches from './services/Caches';
@@ -285,6 +286,7 @@ export default angular.module('ignite-console', [
 .service(...Focus)
 .service(...InetAddress)
 .service(...Messages)
+.service('IgniteErrorParser', ErrorParser)
 .service(...ModelNormalizer)
 .service(...LegacyTable)
 .service(...FormUtils)

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8b3ba49/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js
----------------------------------------------------------------------
diff --git 
a/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js
 
b/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js
index ad76df2..09c4184 100644
--- 
a/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js
+++ 
b/modules/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.js
@@ -66,7 +66,7 @@ const _fullColName = (col) => {
 let paragraphId = 0;
 
 class Paragraph {
-    constructor($animate, $timeout, JavaTypes, paragraph) {
+    constructor($animate, $timeout, JavaTypes, paragraph, errorParser) {
         const self = this;
 
         self.id = 'paragraph-' + paragraphId++;
@@ -146,14 +146,14 @@ class Paragraph {
 
         this.setError = (err) => {
             this.error.root = err;
-            this.error.message = err.message;
+            this.error.message = errorParser.extractMessage(err);
 
             let cause = err;
 
             while (nonNil(cause)) {
                 if (nonEmpty(cause.className) &&
                     _.includes(['SQLException', 'JdbcSQLException', 
'QueryCancelledException'], JavaTypes.shortClassName(cause.className))) {
-                    this.error.message = cause.message || cause.className;
+                    this.error.message = 
errorParser.extractMessage(cause.message || cause.className);
 
                     break;
                 }
@@ -251,16 +251,16 @@ class Paragraph {
 
 // Controller for SQL notebook screen.
 export class NotebookCtrl {
-    static $inject = ['$rootScope', '$scope', '$http', '$q', '$timeout', 
'$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', 
'$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 
'IgniteConfirm', 'AgentManager', 'IgniteChartColors', 'IgniteNotebook', 
'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 
'IgniteActivitiesData', 'JavaTypes', 'IgniteCopyToClipboard', CSV.name];
+    static $inject = ['$rootScope', '$scope', '$http', '$q', '$timeout', 
'$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', 
'$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 
'IgniteConfirm', 'AgentManager', 'IgniteChartColors', 'IgniteNotebook', 
'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 
'IgniteActivitiesData', 'JavaTypes', 'IgniteCopyToClipboard', CSV.name, 
'IgniteErrorParser'];
 
     /**
      * @param {CSV} CSV
      */
-    constructor($root, $scope, $http, $q, $timeout, $interval, $animate, 
$location, $anchorScroll, $state, $filter, $modal, $popover, Loading, 
LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, 
uiGridExporterConstants, Version, ActivitiesData, JavaTypes, 
IgniteCopyToClipboard, CSV) {
+    constructor($root, $scope, $http, $q, $timeout, $interval, $animate, 
$location, $anchorScroll, $state, $filter, $modal, $popover, Loading, 
LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, 
uiGridExporterConstants, Version, ActivitiesData, JavaTypes, 
IgniteCopyToClipboard, CSV, errorParser) {
         const $ctrl = this;
 
         this.CSV = CSV;
-        Object.assign(this, { $root, $scope, $http, $q, $timeout, $interval, 
$animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, 
LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, 
uiGridExporterConstants, Version, ActivitiesData, JavaTypes });
+        Object.assign(this, { $root, $scope, $http, $q, $timeout, $interval, 
$animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, 
LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, 
uiGridExporterConstants, Version, ActivitiesData, JavaTypes, errorParser });
 
         // Define template urls.
         $ctrl.paragraphRateTemplateUrl = paragraphRateTemplateUrl;
@@ -970,7 +970,7 @@ export class NotebookCtrl {
                     $scope.notebook.paragraphs = [];
 
                 $scope.notebook.paragraphs = _.map($scope.notebook.paragraphs,
-                    (paragraph) => new Paragraph($animate, $timeout, 
JavaTypes, paragraph));
+                    (paragraph) => new Paragraph($animate, $timeout, 
JavaTypes, paragraph, this.errorParser));
 
                 if (_.isEmpty($scope.notebook.paragraphs))
                     $scope.addQuery();
@@ -1933,9 +1933,7 @@ export class NotebookCtrl {
 
                 const addToTrace = (item) => {
                     if (nonNil(item)) {
-                        const clsName = _.isEmpty(item.className) ? '' : '[' + 
JavaTypes.shortClassName(item.className) + '] ';
-
-                        scope.content.push((scope.content.length > 0 ? tab : 
'') + clsName + (item.message || ''));
+                        scope.content.push((scope.content.length > 0 ? tab : 
'') + errorParser.extractFullMessage(item));
 
                         addToTrace(item.cause);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8b3ba49/modules/web-console/frontend/app/services/ErrorParser.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/ErrorParser.service.js 
b/modules/web-console/frontend/app/services/ErrorParser.service.js
new file mode 100644
index 0000000..9cda8ed
--- /dev/null
+++ b/modules/web-console/frontend/app/services/ErrorParser.service.js
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+import isEmpty from 'lodash/isEmpty';
+import {nonEmpty} from 'app/utils/lodashMixins';
+
+export default class {
+    static $inject = ['JavaTypes'];
+
+    /**
+     * @param JavaTypes service.
+     */
+    constructor(JavaTypes) {
+        this.JavaTypes = JavaTypes;
+    }
+
+    extractMessage(err, prefix) {
+        prefix = prefix || '';
+
+        if (err) {
+            if (err.hasOwnProperty('data'))
+                err = err.data;
+
+            if (err.hasOwnProperty('message')) {
+                let msg = err.message;
+
+                const traceIndex = msg.indexOf(', trace=');
+
+                if (traceIndex > 0)
+                    msg = msg.substring(0, traceIndex);
+
+                const lastIdx = msg.lastIndexOf(' err=');
+                let msgEndIdx = msg.indexOf(']', lastIdx);
+
+                if (lastIdx > 0 && msgEndIdx > 0) {
+                    let startIdx = msg.indexOf('[', lastIdx);
+
+                    while (startIdx > 0) {
+                        const tmpIdx = msg.indexOf(']', msgEndIdx + 1);
+
+                        if (tmpIdx > 0)
+                            msgEndIdx = tmpIdx;
+
+                        startIdx = msg.indexOf('[', startIdx + 1);
+                    }
+                }
+
+                return prefix + (lastIdx >= 0 ? msg.substring(lastIdx + 5, 
msgEndIdx > 0 ? msgEndIdx : traceIndex) : msg);
+            }
+
+            if (nonEmpty(err.className)) {
+                if (isEmpty(prefix))
+                    prefix = 'Internal cluster error: ';
+
+                return prefix + err.className;
+            }
+
+            return prefix + err;
+        }
+
+        return prefix + 'Internal error.';
+    }
+
+    extractFullMessage(err) {
+        const clsName = _.isEmpty(err.className) ? '' : '[' + 
this.JavaTypes.shortClassName(err.className) + '] ';
+
+        let msg = err.message || '';
+        const traceIndex = msg.indexOf(', trace=');
+
+        if (traceIndex > 0)
+            msg = msg.substring(0, traceIndex);
+
+        return clsName + (msg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/c8b3ba49/modules/web-console/frontend/app/services/Messages.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/Messages.service.js 
b/modules/web-console/frontend/app/services/Messages.service.js
index 170ff04..1337e24 100644
--- a/modules/web-console/frontend/app/services/Messages.service.js
+++ b/modules/web-console/frontend/app/services/Messages.service.js
@@ -16,39 +16,14 @@
  */
 
 import {CancellationError} from 'app/errors/CancellationError';
-import isEmpty from 'lodash/isEmpty';
-import {nonEmpty} from 'app/utils/lodashMixins';
 
 // Service to show various information and error messages.
-export default ['IgniteMessages', ['$alert', ($alert) => {
+export default ['IgniteMessages', ['$alert', 'IgniteErrorParser', ($alert, 
errorParser) => {
     // Common instance of alert modal.
     let msgModal;
 
     const errorMessage = (prefix, err) => {
-        prefix = prefix || '';
-
-        if (err) {
-            if (err.hasOwnProperty('data'))
-                err = err.data;
-
-            if (err.hasOwnProperty('message')) {
-                const msg = err.message;
-                const lastIdx = msg.lastIndexOf(' err=');
-
-                return prefix + (lastIdx >= 0 ? msg.substring(lastIdx + 5, 
msg.indexOf(']', lastIdx)) : msg);
-            }
-
-            if (nonEmpty(err.className)) {
-                if (isEmpty(prefix))
-                    prefix = 'Internal cluster error: ';
-
-                return prefix + err.className;
-            }
-
-            return prefix + err;
-        }
-
-        return prefix + 'Internal error.';
+        return errorParser.extractMessage(err, prefix);
     };
 
     const hideAlert = () => {

Reply via email to