public inbox for [email protected]  
help / color / mirror / Atom feed
From: Murtuza Zabuawala <[email protected]>
To: Joao De Almeida Pereira <[email protected]>
Cc: Dave Page <[email protected]>
Cc: pgadmin-hackers <[email protected]>
Subject: Re: [pgAdmin4][RM#3235] Code refactoring in Query tool
Date: Wed, 4 Apr 2018 14:13:10 +0530
Message-ID: <CAKKotZS5pAJ70iNJkvUTLr5jZ7nJNArwkiQyfgaz3y9csdarWg@mail.gmail.com> (raw)
In-Reply-To: <CAE+jjang5oqj8-c_VhryAET8aaj6USYtRuLmY8gKctC8wz475w@mail.gmail.com>
References: <CAKKotZRidfdPkSe=2wiaDsz_F3sAXdWZs_1SQLFks1YeP24UTQ@mail.gmail.com>
	<CA+OCxoygT-+xezSAboURa9E9myQCX2GbO4DCFg7yY+umHhEa5g@mail.gmail.com>
	<CAKKotZRwxcozrSic25xSCtK_z7bdnksrF2_4GSeWi=6zDUSw_g@mail.gmail.com>
	<CAE+jjang5oqj8-c_VhryAET8aaj6USYtRuLmY8gKctC8wz475w@mail.gmail.com>

Hi,

Thank you Victoria & Joao for reviewing.
PFA updated patch.

On Wed, Apr 4, 2018 at 12:26 AM, Joao De Almeida Pereira <
[email protected]> wrote:

> Hi Murtuza
>
> It is really good to see other patches that are just refactoring code.
>
> We have some suggestions:
> - We are trying to use === instead of == because === ensure that the type
> is also checked (https://developer.mozilla.org/en-US/docs/Web/JavaScript/
> Equality_comparisons_and_sameness)
>
​Done​


- Now that we are refactoring some code, maybe we should keep some
> consistency on the way we name functions and variables.
>
We should use camelCase for names instead of snake_case. In general, if you
> see a function or variable name that doesn't fit the desired syntax or if a
> block of code seems confusing, it is better to refactor it.
>
Done​, I have also changed other variables.​
BTW I'm using camelCase convention from last few patches :)

- By the name of the function is_new_transaction_required, it describes
> what the function represents but doesn't seem to explain the full scope of
> the function. What do you think about the name: httpResponseRequiresNewT
> ransaction
>
​Done​


- The extraction doesn't look like it matches the code removed
>

> -            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e))
> {
> -              self.save_state('_explain_timing', []);
> -              return pgAdmin.Browser.UserManagement.pga_login();
> -            }
> -
> -            if(transaction.is_new_transaction_required(e)) {
> -              self.save_state('_explain_timing', []);
> -              return self.init_transaction();
> -            }
> -
> -            alertify.alert(gettext('Explain options error'),
> -              gettext('Error occurred while setting timing option in
> explain.')
> +            let msg = httpErrorHandler.handleQueryToolAjaxError(
> +              pgAdmin, self, e, '_explain_timing', null, true
>              );
> +            alertify.alert(gettext('Explain options error'), msg);
> In this case we are only saving state if the following conditions are
> true:
> isNotConnectedToThePythonServer and httpResponseJSONIsPresent and
> connectionLostToPostgresDatabase and shouldSaveState
> That is not the case on the removed code.
>
​I think the *null* value got your attention b
ut actually I have a check in ​*handleQueryToolAjaxError *which will make
it array [] with respect to arguments for the state to save, Anyways I have
also changed it to pass [] instead of null for better clarity.
We have all those checks in our function so it check for those condition
and save the state only if those returns True.

- The functions extracted when are called do not use all the parameters.
> This tells us that the function groups too much functionality that is not
> used in same cases. Maybe we should split this function into smaller
> functions that do each part.
>
​We already had split up the function in two part.
​

>
>
> Thanks
> Victoria & Joao
>
> On Tue, Apr 3, 2018 at 11:38 AM Murtuza Zabuawala <murtuza.zabuawala@
> enterprisedb.com> wrote:
>
>> Hi Dave,
>>
>> PFA updated patch, I've renamed it to query_tool_http_error_handler.js
>> & query_tool_http_error_handler_spec.js respectively.
>>
>> --
>> Regards,
>> Murtuza Zabuawala
>> EnterpriseDB: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>>
>> On Tue, Apr 3, 2018 at 7:43 PM, Dave Page <[email protected]> wrote:
>>
>>> HI
>>>
>>> On Tue, Apr 3, 2018 at 12:27 PM, Murtuza Zabuawala <murtuza.zabuawala@
>>> enterprisedb.com> wrote:
>>>
>>>> Hi,
>>>>
>>>> PFA patch to extract the common code from query tool to handle ajax
>>>> errors & connection handling, Also added unit tests around extracted code.
>>>>
>>>
>>> Looks good to me, except, I wonder if we should rename
>>> is_new_transaction_required.js/is_new_transaction_required_spec.js to
>>> something a little more generic; maybe conn_tx_handler_funcs.js? Not sure I
>>> like that though.
>>>
>>>
>>> --
>>> Dave Page
>>> Blog: http://pgsnake.blogspot.com
>>> Twitter: @pgsnake
>>>
>>> EnterpriseDB UK: http://www.enterprisedb.com
>>> The Enterprise PostgreSQL Company
>>>
>>
>>


Attachments:

  [application/octet-stream] RM_3235_v2.diff (56.3K, 3-RM_3235_v2.diff)
  download | inline diff:
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
index 9c36f28..333a3a2 100644
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -11,7 +11,7 @@ import gettext from '../gettext';
 import $ from 'jquery';
 import url_for from '../url_for';
 import axios from 'axios';
-import * as transaction from './is_new_transaction_required';
+import * as httpErrorHandler from './query_tool_http_error_handler';
 
 class LoadingScreen {
   constructor(sqlEditor) {
@@ -152,8 +152,8 @@ class ExecuteQuery {
 
         const errorData = error.response.data;
 
-        if (self.userManagement.is_pga_login_required(errorData)) {
-          return self.userManagement.pga_login();
+        if (self.userManagement.isPgaLoginRequired(errorData)) {
+          return self.userManagement.pgaLogin();
         }
 
         let msg = ExecuteQuery.extractErrorMessage(errorData);
@@ -198,18 +198,18 @@ class ExecuteQuery {
       return;
     }
 
-    if (this.userManagement.is_pga_login_required(httpMessage.response)) {
-      this.sqlServerObject.save_state('execute', [this.explainPlan]);
-      this.userManagement.pga_login();
+    if (this.userManagement.isPgaLoginRequired(httpMessage.response)) {
+      this.sqlServerObject.saveState('execute', [this.explainPlan]);
+      this.userManagement.pgaLogin();
     }
 
-    if (transaction.is_new_transaction_required(httpMessage.response)) {
-      this.sqlServerObject.save_state('execute', [this.explainPlan]);
-      this.sqlServerObject.init_transaction();
+    if (httpErrorHandler.httpResponseRequiresNewTransaction(httpMessage.response)) {
+      this.sqlServerObject.saveState('execute', [this.explainPlan]);
+      this.sqlServerObject.initTransaction();
     }
 
     if (this.wasDatabaseConnectionLost(httpMessage)) {
-      this.sqlServerObject.save_state('execute', [this.explainPlan]);
+      this.sqlServerObject.saveState('execute', [this.explainPlan]);
       this.sqlServerObject.handle_connection_lost(false, httpMessage);
     }
 
diff --git a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js b/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
deleted file mode 100644
index e009611..0000000
--- a/web/pgadmin/static/js/sqleditor/is_new_transaction_required.js
+++ /dev/null
@@ -1,23 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2018, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-export function is_new_transaction_required(xhr) {
-  /* If responseJSON is undefined then it could be object of
-   * axios(Promise HTTP) response, so we should check accordingly.
-   */
-  if (xhr.responseJSON === undefined && xhr.data !== undefined) {
-    return xhr.status === 404 && xhr.data &&
-              xhr.data.info &&
-              xhr.data.info === 'DATAGRID_TRANSACTION_REQUIRED';
-  }
-
-  return xhr.status === 404 && xhr.responseJSON &&
-    xhr.responseJSON.info &&
-    xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
-}
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_http_error_handler.js b/web/pgadmin/static/js/sqleditor/query_tool_http_error_handler.js
new file mode 100644
index 0000000..ae224ed
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/query_tool_http_error_handler.js
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////////////////
+import gettext from 'sources/gettext';
+
+export function httpResponseRequiresNewTransaction(xhr) {
+  /* If responseJSON is undefined then it could be object of
+   * axios(Promise HTTP) response, so we should check accordingly.
+   */
+  if (xhr.responseJSON === undefined && xhr.data !== undefined) {
+    return xhr.status === 404 && xhr.data &&
+              xhr.data.info &&
+              xhr.data.info === 'DATAGRID_TRANSACTION_REQUIRED';
+  }
+
+  return xhr.status === 404 && xhr.responseJSON &&
+    xhr.responseJSON.info &&
+    xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
+}
+
+// Allow us to redirect to login dialog and if required then re-initiate the transaction
+export function handleLoginRequiredAndTransactionRequired(
+  pgAdmin, handler, exception, stateToSave, stateParameters, checkTransaction
+) {
+  stateParameters = stateParameters && stateParameters.length > 0 ? stateParameters : [];
+  if (pgAdmin.Browser.UserManagement.isPgaLoginRequired(exception)) {
+    if (stateToSave) {
+      handler.saveState(stateToSave, stateParameters);
+    }
+    return pgAdmin.Browser.UserManagement.pgaLogin();
+  }
+
+  if(checkTransaction && httpResponseRequiresNewTransaction(exception)) {
+    if (stateToSave) {
+      handler.saveState(stateToSave, stateParameters);
+    }
+    return handler.initTransaction();
+  }
+}
+
+// Allow us to handle the AJAX error from Query tool
+export function handleQueryToolAjaxError(
+  pgAdmin, handler, exception, stateToSave, stateParameters, checkTransaction
+) {
+  if (exception.readyState === 0) {
+    return gettext('Not connected to the server or the connection to the server has been closed.');
+  }
+
+  handleLoginRequiredAndTransactionRequired(
+    pgAdmin, handler, exception, stateToSave, stateParameters, checkTransaction
+  );
+
+  let msg = exception.responseText;
+  if (exception.responseJSON !== undefined) {
+    if(exception.responseJSON.errormsg !== undefined) {
+      msg = exception.responseJSON.errormsg;
+    }
+
+    if(exception.status === 503 && exception.responseJSON.info !== undefined &&
+        exception.responseJSON.info == 'CONNECTION_LOST') {
+      setTimeout(function() {
+        if (stateToSave) {
+          handler.saveState(stateToSave, stateParameters);
+        }
+        handler.handle_connection_lost(false, exception);
+      });
+    }
+  }
+
+  return msg;
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 0409a87..60dacbb 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -13,7 +13,7 @@ define('tools.querytool', [
   'sources/selection/set_staged_rows',
   'sources/sqleditor_utils',
   'sources/sqleditor/execute_query',
-  'sources/sqleditor/is_new_transaction_required',
+  'sources/sqleditor/query_tool_http_error_handler',
   'sources/history/index.js',
   'sources/../jsx/history/query_history',
   'react', 'react-dom',
@@ -33,7 +33,7 @@ define('tools.querytool', [
 ], function(
   babelPollyfill, gettext, url_for, $, _, S, alertify, pgAdmin, Backbone, codemirror,
   pgExplain, GridSelector, ActiveCellCapture, clipboard, copyData, RangeSelectionHelper, handleQueryOutputKeyboardEvent,
-  XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, transaction,
+  XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler,
   HistoryBundle, queryHistory, React, ReactDOM,
   keyboardShortcuts, queryToolActions, Datagrid, modifyAnimation,
   calculateQueryRunTime, callRenderAfterPoll) {
@@ -486,12 +486,9 @@ define('tools.querytool', [
                 });
               },
               error:function(e) {
-                if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-                  return pgAdmin.Browser.UserManagement.pga_login();
-                }
-                if(transaction.is_new_transaction_required(e)) {
-                  return self.init_transaction();
-                }
+                return httpErrorHandler.handleLoginRequiredAndTransactionRequired(
+                  pgAdmin, self, e, null, [], false
+                );
               },
             });
           }.bind(ctx),
@@ -1142,16 +1139,11 @@ define('tools.querytool', [
           if (typeof cb == 'function') {
             cb();
           }
-          if (e.readyState == 0) {
-            self.update_msg_history(false,
-              gettext('Not connected to the server or the connection to the server has been closed.')
-            );
-            return;
-          }
 
-          if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-            pgAdmin.Browser.UserManagement.pga_login();
-          }
+          let msg = httpErrorHandler.handleQueryToolAjaxError(
+            pgAdmin, self, e, null, [], false
+          );
+          self.update_msg_history(false, msg);
         },
       });
     },
@@ -1815,10 +1807,10 @@ define('tools.querytool', [
           self.warn_before_continue();
         });
         pgBrowser.Events.on('pgadmin:user:logged-in', function() {
-          self.init_transaction();
+          self.initTransaction();
         });
       },
-      save_state: function(fn, args) {
+      saveState: function(fn, args) {
         if (fn) {
           this.state = {
             'fn': fn,
@@ -1829,7 +1821,7 @@ define('tools.querytool', [
         }
       },
 
-      init_transaction: function() {
+      initTransaction: function() {
         var url_endpoint;
         if (this.is_query_tool) {
           url_endpoint = 'datagrid.initialize_query_tool';
@@ -1898,7 +1890,7 @@ define('tools.querytool', [
             if ('fn' in self.state) {
               var fn = self.state['fn'],
                 args = self.state['args'];
-              self.save_state();
+              self.saveState();
               if (args.indexOf('connect') == -1) {
                 args.push('connect');
               }
@@ -1906,7 +1898,7 @@ define('tools.querytool', [
               self[fn].apply(self, args);
             }
           }, function() {
-            self.save_state();
+            self.saveState();
           })
           .set({
             labels: {
@@ -1925,28 +1917,22 @@ define('tools.querytool', [
           if (res.success == 1) {
             alertify.success(res.info);
             if (create_transaction) {
-              self.init_transaction();
+              self.initTransaction();
             } else if ('fn' in self.state) {
               var fn = self.state['fn'],
                 args = self.state['args'];
-              self.save_state();
+              self.saveState();
               self[fn].apply(self, args);
             }
           }
         })
         .fail(function(xhr) {
-          if (pgAdmin.Browser.UserManagement.is_pga_login_required(xhr)) {
-            pgAdmin.Browser.UserManagement.pga_login();
-          } else {
-            if(xhr.responseJSON &&
-                xhr.responseJSON.result) {
-              alertify.dlgGetServerPass(gettext('Connect to Server'),
-                xhr.responseJSON.result);
-            } else {
-              alertify.dlgGetServerPass(gettext('Connect to Server'),
-                xhr.responseText);
-            }
-          }
+          let msg = httpErrorHandler.handleQueryToolAjaxError(
+            pgAdmin, self, xhr, null, [], false
+          );
+          alertify.dlgGetServerPass(
+            gettext('Connect to Server'), msg
+          );
         });
       },
       /* This function is used to create instance of SQLEditorView,
@@ -2005,22 +1991,13 @@ define('tools.querytool', [
                 self.init_events();
               },
               error: function(jqx) {
-                var msg = '';
+                let msg = '';
                 self.init_events();
 
-                if (pgAdmin.Browser.UserManagement.is_pga_login_required(jqx)) {
-                  return pgAdmin.Browser.UserManagement.pga_login();
-                }
+                msg = httpErrorHandler.handleQueryToolAjaxError(
+                  pgAdmin, self, jqx, null, [], false
+                );
 
-                /* Error from the server */
-                if (jqx.status == 410 || jqx.status == 500) {
-                  try {
-                    var data = $.parseJSON(jqx.responseText);
-                    msg = data.errormsg;
-                  } catch (e) {
-                    msg = jqx.responseText;
-                  }
-                }
                 pgBrowser.report_error(
                   S(gettext('Error fetching SQL for script: %s.')).sprintf(msg).value()
                 );
@@ -2189,37 +2166,9 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (e.readyState == 0) {
-              self.update_msg_history(false,
-                gettext('Not connected to the server or the connection to the server has been closed.')
-              );
-              return;
-            }
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_run_query', []);
-              pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_run_query', []);
-              self.init_transaction();
-            }
-
-            var msg = e.responseText;
-            if (e.responseJSON != undefined) {
-              if(e.responseJSON.errormsg != undefined) {
-                msg = e.responseJSON.errormsg;
-              }
-
-              if(e.status == 503 && e.responseJSON.info != undefined &&
-                  e.responseJSON.info == 'CONNECTION_LOST') {
-                setTimeout(function() {
-                  self.save_state('_run_query', []);
-                  self.handle_connection_lost(false, e);
-                });
-              }
-            }
-
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_run_query', [], true
+            );
             self.update_msg_history(false, msg);
           },
         });
@@ -2830,38 +2779,10 @@ define('tools.querytool', [
               }
             },
             error: function(e) {
-              if (e.readyState == 0) {
-                self.update_msg_history(false,
-                  gettext('Not connected to the server or the connection to the server has been closed.')
-                );
-                return;
-              }
-
-              if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-                self.save_state('_save', [view, controller, save_as]);
-                pgAdmin.Browser.UserManagement.pga_login();
-              }
-
-              if(transaction.is_new_transaction_required(e)) {
-                self.save_state('_save', [view, controller, save_as]);
-                self.init_transaction();
-              }
-
-              var msg = e.responseText;
-              if (e.responseJSON != undefined) {
-                if(e.responseJSON.errormsg != undefined) {
-                  msg = e.responseJSON.errormsg;
-                }
-
-                if(e.status == 503 && e.responseJSON.info != undefined &&
-                    e.responseJSON.info == 'CONNECTION_LOST') {
-                  setTimeout(function() {
-                    self.save_state('_save', [view, controller, save_as]);
-                    self.handle_connection_lost(false, e);
-                  });
-                }
-              }
-
+              let stateParams = [view, controller, save_as];
+              let msg = httpErrorHandler.handleQueryToolAjaxError(
+                pgAdmin, self, e, '_save', stateParams, true
+              );
               self.update_msg_history(false, msg);
             },
           });
@@ -3007,13 +2928,11 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_select_file_handler', [_e]);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            var errmsg = $.parseJSON(e.responseText).errormsg;
-            alertify.error(errmsg);
+            let stateParams = [_e];
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_select_file_handler', stateParams, false
+            );
+            alertify.error(msg);
             // hide cursor
             $busy_icon_div.removeClass('show_progress');
           },
@@ -3059,17 +2978,11 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_save_file_handler', [_e]);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            var errmsg = $.parseJSON(e.responseText).errormsg;
-            setTimeout(
-              function() {
-                alertify.error(errmsg);
-              }, 10
+            let stateParams = [_e];
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_save_file_handler', stateParams, false
             );
+            alertify.error(msg);
           },
         });
       },
@@ -3165,36 +3078,9 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_show_filter', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_show_filter', []);
-              return self.init_transaction();
-            }
-
-            var msg;
-            if (e.readyState == 0) {
-              msg =
-                gettext('Not connected to the server or the connection to the server has been closed.');
-            } else {
-              msg = e.responseText;
-              if (e.responseJSON != undefined) {
-                if(e.responseJSON.errormsg != undefined) {
-                  msg = e.responseJSON.errormsg;
-                }
-                if(e.status == 503 && e.responseJSON.info != undefined &&
-                    e.responseJSON.info == 'CONNECTION_LOST') {
-                  setTimeout(function() {
-                    self.save_state('_show_filter', []);
-                    self.handle_connection_lost(false, e);
-                  });
-                }
-              }
-            }
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_show_filter', [], true
+            );
             setTimeout(
               function() {
                 alertify.alert(gettext('Get Filter Error'), msg);
@@ -3255,42 +3141,10 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_include_filter', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_include_filter', []);
-              return self.init_transaction();
-            }
-
-            setTimeout(
-              function() {
-                if (e.readyState == 0) {
-                  alertify.alert(gettext('Filter By Selection Error'),
-                    gettext('Not connected to the server or the connection to the server has been closed.')
-                  );
-                  return;
-                }
-
-                var msg = e.responseText;
-                if (e.responseJSON != undefined) {
-                  if(e.responseJSON.errormsg != undefined) {
-                    msg = e.responseJSON.errormsg;
-                  }
-                  if(e.status == 503 && e.responseJSON.info != undefined &&
-                      e.responseJSON.info == 'CONNECTION_LOST') {
-                    setTimeout(function() {
-                      self.save_state('_include_filter', []);
-                      self.handle_connection_lost(false, e);
-                    });
-                  }
-                }
-
-                alertify.alert(gettext('Filter By Selection Error'), msg);
-              }, 10
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_include_filter', [], true
             );
+            alertify.alert(gettext('Filter By Selection Error'), msg);
           },
         });
       },
@@ -3346,42 +3200,10 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_exclude_filter', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_exclude_filter', []);
-              return self.init_transaction();
-            }
-
-            setTimeout(
-              function() {
-                if (e.readyState == 0) {
-                  alertify.alert(gettext('Filter Exclude Selection Error'),
-                    gettext('Not connected to the server or the connection to the server has been closed.')
-                  );
-                  return;
-                }
-
-                var msg = e.responseText;
-                if (e.responseJSON != undefined) {
-                  if(e.responseJSON.errormsg != undefined) {
-                    msg = e.responseJSON.errormsg;
-                  }
-                  if(e.status == 503 && e.responseJSON.info != undefined &&
-                      e.responseJSON.info == 'CONNECTION_LOST') {
-                    setTimeout(function() {
-                      self.save_state('_exclude_filter', []);
-                      self.handle_connection_lost(false, e);
-                    });
-                  }
-                }
-
-                alertify.alert(gettext('Filter Exclude Selection Error'), msg);
-              }, 10
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_exclude_filter', [], true
             );
+            alertify.alert(gettext('Filter Exclude Selection Error'), msg);
           },
         });
       },
@@ -3416,42 +3238,10 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_remove_filter', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_remove_filter', []);
-              return self.init_transaction();
-            }
-
-            setTimeout(
-              function() {
-                if (e.readyState == 0) {
-                  alertify.alert(gettext('Remove Filter Error'),
-                    gettext('Not connected to the server or the connection to the server has been closed.')
-                  );
-                  return;
-                }
-
-                var msg = e.responseText;
-                if (e.responseJSON != undefined) {
-                  if(e.responseJSON.errormsg != undefined) {
-                    msg = e.responseJSON.errormsg;
-                  }
-                  if(e.status == 503 && e.responseJSON.info != undefined &&
-                      e.responseJSON.info == 'CONNECTION_LOST') {
-                    setTimeout(function() {
-                      self.save_state('_remove_filter', []);
-                      self.handle_connection_lost(false, e);
-                    });
-                  }
-                }
-
-                alertify.alert(gettext('Remove Filter Error'), msg);
-              }
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_remove_filter', [], true
             );
+            alertify.alert(gettext('Remove Filter Error'), msg);
           },
         });
       },
@@ -3491,42 +3281,10 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_apply_filter', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_apply_filter', []);
-              return self.init_transaction();
-            }
-
-            setTimeout(
-              function() {
-                if (e.readyState == 0) {
-                  alertify.alert(gettext('Apply Filter Error'),
-                    gettext('Not connected to the server or the connection to the server has been closed.')
-                  );
-                  return;
-                }
-
-                var msg = e.responseText;
-                if (e.responseJSON != undefined) {
-                  if(e.responseJSON.errormsg != undefined) {
-                    msg = e.responseJSON.errormsg;
-                  }
-                  if(e.status == 503 && e.responseJSON.info != undefined &&
-                      e.responseJSON.info == 'CONNECTION_LOST') {
-                    setTimeout(function() {
-                      self.save_state('_apply_filter', []);
-                      self.handle_connection_lost(false, e);
-                    });
-                  }
-                }
-
-                alertify.alert(gettext('Apply Filter Error'), msg);
-              }, 10
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_apply_filter', [], true
             );
+            alertify.alert(gettext('Apply Filter Error'), msg);
           },
         });
       },
@@ -3646,42 +3404,10 @@ define('tools.querytool', [
           },
           error: function(e) {
             self.trigger('pgadmin-sqleditor:loading-icon:hide');
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_set_limit', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_set_limit', []);
-              return self.init_transaction();
-            }
-
-            setTimeout(
-              function() {
-                if (e.readyState == 0) {
-                  alertify.alert(gettext('Change limit Error'),
-                    gettext('Not connected to the server or the connection to the server has been closed.')
-                  );
-                  return;
-                }
-
-                var msg = e.responseText;
-                if (e.responseJSON != undefined) {
-                  if(e.responseJSON.errormsg != undefined) {
-                    msg = e.responseJSON.errormsg;
-                  }
-                  if(e.status == 503 && e.responseJSON.info != undefined &&
-                      e.responseJSON.info == 'CONNECTION_LOST') {
-                    setTimeout(function() {
-                      self.save_state('_set_limit', []);
-                      self.handle_connection_lost(false, e);
-                    });
-                  }
-                }
-
-                alertify.alert(gettext('Change limit Error'), msg);
-              }, 10
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_set_limit', [], true
             );
+            alertify.alert(gettext('Change limit Error'), msg);
           },
         });
       },
@@ -3805,23 +3531,9 @@ define('tools.querytool', [
           error: function(e) {
             self.disable_tool_buttons(false);
 
-            if (e.readyState == 0) {
-              alertify.alert(gettext('Cancel Query Error'),
-                gettext('Not connected to the server or the connection to the server has been closed.')
-              );
-              return;
-            }
-
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_cancel_query', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            var msg = e.responseText;
-            if (e.responseJSON != undefined &&
-              e.responseJSON.errormsg != undefined)
-              msg = e.responseJSON.errormsg;
-
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_cancel_query', [], false
+            );
             alertify.alert(gettext('Cancel Query Error'), msg);
           },
         });
@@ -3866,38 +3578,10 @@ define('tools.querytool', [
               alertify.alert(gettext('Auto Rollback Error'), res.data.result);
           },
           error: function(e) {
-            if (e.readyState == 0) {
-              alertify.alert(gettext('Auto Rollback Error'),
-                gettext('Not connected to the server or the connection to the server has been closed.')
-              );
-              return;
-            }
-
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_auto_rollback', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_auto_rollback', []);
-              self.init_transaction();
-            }
-
-            var msg = e.responseText;
-            if (e.responseJSON != undefined) {
-              if(e.responseJSON.errormsg != undefined) {
-                msg = e.responseJSON.errormsg;
-              }
-
-              if(e.status == 503 && e.responseJSON.info != undefined &&
-                  e.responseJSON.info == 'CONNECTION_LOST') {
-                setTimeout(function() {
-                  self.save_state('_auto_rollback', []);
-                  self.handle_connection_lost(false, e);
-                });
-              }
-            }
 
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_auto_rollback', [], true
+            );
             alertify.alert(gettext('Auto Rollback Error'), msg);
           },
         });
@@ -3927,38 +3611,9 @@ define('tools.querytool', [
               alertify.alert(gettext('Auto Commit Error'), res.data.result);
           },
           error: function(e) {
-            if (e.readyState == 0) {
-              alertify.alert(gettext('Auto Commit Error'),
-                gettext('Not connected to the server or the connection to the server has been closed.')
-              );
-              return;
-            }
-
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_auto_commit', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_auto_commit', []);
-              return self.init_transaction();
-            }
-
-            var msg = e.responseText;
-            if (e.responseJSON != undefined) {
-              if(e.responseJSON.errormsg != undefined) {
-                msg = e.responseJSON.errormsg;
-              }
-
-              if(e.status == 503 && e.responseJSON.info != undefined &&
-                  e.responseJSON.info == 'CONNECTION_LOST') {
-                setTimeout(function() {
-                  self.save_state('_auto_commit', []);
-                  self.handle_connection_lost(false, e);
-                });
-              }
-            }
-
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_auto_commit', [], true
+            );
             alertify.alert(gettext('Auto Commit Error'), msg);
           },
         });
@@ -3995,21 +3650,10 @@ define('tools.querytool', [
             }
           },
           error: function(e) {
-
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_explain_verbose', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_explain_verbose', []);
-              return self.init_transaction();
-            }
-
-            alertify.alert(gettext('Explain options error'),
-              gettext('Error occurred while setting verbose option in explain.')
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_explain_verbose', [], true
             );
-            return;
+            alertify.alert(gettext('Explain options error'), msg);
           },
         });
       },
@@ -4045,19 +3689,10 @@ define('tools.querytool', [
             }
           },
           error: function(e) {
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_explain_costs', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_explain_costs', []);
-              return self.init_transaction();
-            }
-
-            alertify.alert(gettext('Explain options error'),
-              gettext('Error occurred while setting costs option in explain.')
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_explain_costs', [], true
             );
+            alertify.alert(gettext('Explain options error'), msg);
           },
         });
       },
@@ -4093,19 +3728,10 @@ define('tools.querytool', [
             }
           },
           error: function(e) {
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_explain_buffers', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_explain_buffers', []);
-              return self.init_transaction();
-            }
-
-            alertify.alert(gettext('Explain options error'),
-              gettext('Error occurred while setting buffers option in explain.')
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_explain_buffers', [], true
             );
+            alertify.alert(gettext('Explain options error'), msg);
           },
         });
       },
@@ -4140,19 +3766,10 @@ define('tools.querytool', [
             }
           },
           error: function(e) {
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('_explain_timing', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('_explain_timing', []);
-              return self.init_transaction();
-            }
-
-            alertify.alert(gettext('Explain options error'),
-              gettext('Error occurred while setting timing option in explain.')
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, '_explain_timing', [], true
             );
+            alertify.alert(gettext('Explain options error'), msg);
           },
         });
       },
@@ -4254,28 +3871,18 @@ define('tools.querytool', [
             }
           },
           error: function(e) {
-            if (pgAdmin.Browser.UserManagement.is_pga_login_required(e)) {
-              self.save_state('get_preferences', []);
-              return pgAdmin.Browser.UserManagement.pga_login();
-            }
-
-            if(transaction.is_new_transaction_required(e)) {
-              self.save_state('get_preferences', []);
-              return self.init_transaction();
-            }
-
-            updateUI();
-            alertify.alert(
-              gettext('Get Preferences error'),
-              gettext('Error occurred while getting query tool options.')
+            let msg = httpErrorHandler.handleQueryToolAjaxError(
+              pgAdmin, self, e, 'get_preferences', [], true
             );
+            updateUI();
+            alertify.alert(gettext('Get Preferences error'), msg);
           },
         });
       },
       close: function() {
         var self = this;
 
-        pgBrowser.Events.off('pgadmin:user:logged-in', this.init_transaction);
+        pgBrowser.Events.off('pgadmin:user:logged-in', this.initTransaction);
         _.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(panel) {
           if (panel.isVisible()) {
             window.onbeforeunload = null;
diff --git a/web/pgadmin/tools/user_management/static/js/user_management.js b/web/pgadmin/tools/user_management/static/js/user_management.js
index 2627328..dcf65cb 100644
--- a/web/pgadmin/tools/user_management/static/js/user_management.js
+++ b/web/pgadmin/tools/user_management/static/js/user_management.js
@@ -129,7 +129,7 @@ define([
       alertify.ChangePassword(title, url).resizeTo('75%', '70%');
     },
 
-    is_pga_login_required(xhr) {
+    isPgaLoginRequired(xhr) {
       /* If responseJSON is undefined then it could be object of
        * axios(Promise HTTP) response, so we should check accordingly.
        */
@@ -145,7 +145,7 @@ define([
     },
 
     // Callback to draw pgAdmin4 login dialog.
-    pga_login: function(url) {
+    pgaLogin: function(url) {
       var title = gettext('pgAdmin 4 login');
       url = url || url_for('security.login');
       if(!alertify.PgaLogin) {
diff --git a/web/regression/javascript/sqleditor/execute_query_spec.js b/web/regression/javascript/sqleditor/execute_query_spec.js
index 5f92dc5..06fefff 100644
--- a/web/regression/javascript/sqleditor/execute_query_spec.js
+++ b/web/regression/javascript/sqleditor/execute_query_spec.js
@@ -8,7 +8,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 import * as subject from 'sources/sqleditor/execute_query';
-import * as transaction from 'sources/sqleditor/is_new_transaction_required';
+import * as httpErrorHandler from 'sources/sqleditor/query_tool_http_error_handler';
 import axios from 'axios';
 import MockAdapter from 'axios-mock-adapter';
 import $ from 'jquery';
@@ -27,8 +27,8 @@ describe('ExecuteQuery', () => {
     networkMock = new MockAdapter(axios);
     jasmine.addMatchers({jQuerytoHaveBeenCalledWith: jQuerytoHaveBeenCalledWith});
     userManagementMock = jasmine.createSpyObj('UserManagement', [
-      'is_pga_login_required',
-      'pga_login',
+      'isPgaLoginRequired',
+      'pgaLogin',
     ]);
 
     sqlEditorMock = jasmine.createSpyObj('SqlEditor', [
@@ -40,14 +40,14 @@ describe('ExecuteQuery', () => {
       'update_msg_history',
       '_highlight_error',
       '_init_polling_flags',
-      'save_state',
-      'init_transaction',
+      'saveState',
+      'initTransaction',
       'handle_connection_lost',
     ]);
     sqlEditorMock.transId = 123;
     sqlEditorMock.rows_affected = 1000;
     executeQuery = new subject.ExecuteQuery(sqlEditorMock, userManagementMock);
-    isNewTransactionRequiredMock = spyOn(transaction, 'is_new_transaction_required');
+    isNewTransactionRequiredMock = spyOn(httpErrorHandler, 'httpResponseRequiresNewTransaction');
   });
 
   afterEach(() => {
@@ -272,7 +272,7 @@ describe('ExecuteQuery', () => {
           describe('when JSON response is available', () => {
             describe('when login is not required', () => {
               beforeEach(() => {
-                userManagementMock.is_pga_login_required.and.returnValue(false);
+                userManagementMock.isPgaLoginRequired.and.returnValue(false);
                 response = {responseJSON: errorMessageJson};
                 networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
 
@@ -336,7 +336,7 @@ describe('ExecuteQuery', () => {
               it('should not login is displayed', (done) => {
                 setTimeout(
                   () => {
-                    expect(userManagementMock.pga_login).not
+                    expect(userManagementMock.pgaLogin).not
                       .toHaveBeenCalled();
                     done();
                   }, 0);
@@ -345,7 +345,7 @@ describe('ExecuteQuery', () => {
 
             describe('when login is required', () => {
               beforeEach(() => {
-                userManagementMock.is_pga_login_required.and.returnValue(true);
+                userManagementMock.isPgaLoginRequired.and.returnValue(true);
                 response = {responseJSON: errorMessageJson};
                 networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
 
@@ -409,7 +409,7 @@ describe('ExecuteQuery', () => {
               it('should login is displayed', (done) => {
                 setTimeout(
                   () => {
-                    expect(userManagementMock.pga_login)
+                    expect(userManagementMock.pgaLogin)
                       .toHaveBeenCalled();
                     done();
                   }, 0);
@@ -420,7 +420,7 @@ describe('ExecuteQuery', () => {
           describe('when no JSON response is available', () => {
             describe('when login is not required', () => {
               beforeEach(() => {
-                userManagementMock.is_pga_login_required.and.returnValue(false);
+                userManagementMock.isPgaLoginRequired.and.returnValue(false);
                 response = {
                   errormsg: errorMessageText,
                 };
@@ -486,7 +486,7 @@ describe('ExecuteQuery', () => {
               it('should login is not displayed', (done) => {
                 setTimeout(
                   () => {
-                    expect(userManagementMock.pga_login).not
+                    expect(userManagementMock.pgaLogin).not
                       .toHaveBeenCalled();
                     done();
                   }, 0);
@@ -495,7 +495,7 @@ describe('ExecuteQuery', () => {
 
             describe('when login is required', () => {
               beforeEach(() => {
-                userManagementMock.is_pga_login_required.and.returnValue(true);
+                userManagementMock.isPgaLoginRequired.and.returnValue(true);
                 response = {
                   errormsg: errorMessageText,
                 };
@@ -561,7 +561,7 @@ describe('ExecuteQuery', () => {
               it('should login is displayed', (done) => {
                 setTimeout(
                   () => {
-                    expect(userManagementMock.pga_login)
+                    expect(userManagementMock.pgaLogin)
                       .toHaveBeenCalled();
                     done();
                   }, 0);
@@ -633,7 +633,7 @@ describe('ExecuteQuery', () => {
             it('should login is not displayed', (done) => {
               setTimeout(
                 () => {
-                  expect(userManagementMock.pga_login).not
+                  expect(userManagementMock.pgaLogin).not
                     .toHaveBeenCalled();
                   done();
                 }, 0);
@@ -1366,7 +1366,7 @@ describe('ExecuteQuery', () => {
       describe('when error is returned by the server', () => {
         describe('when login is not required', () => {
           beforeEach(() => {
-            userManagementMock.is_pga_login_required.and.returnValue(false);
+            userManagementMock.isPgaLoginRequired.and.returnValue(false);
             response.errormsg = 'some error message';
             networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
 
@@ -1422,19 +1422,19 @@ describe('ExecuteQuery', () => {
 
           it('should not save the state', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.save_state).not.toHaveBeenCalled();
+              expect(sqlEditorMock.saveState).not.toHaveBeenCalled();
             }, 0);
           });
 
           it('should not display pga login', () => {
             setTimeout(() => {
-              expect(userManagementMock.pga_login).not.toHaveBeenCalled();
+              expect(userManagementMock.pgaLogin).not.toHaveBeenCalled();
             }, 0);
           });
         });
         describe('when login is required', () => {
           beforeEach(() => {
-            userManagementMock.is_pga_login_required.and.returnValue(true);
+            userManagementMock.isPgaLoginRequired.and.returnValue(true);
             response.errormsg = 'some error message';
             networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
 
@@ -1490,7 +1490,7 @@ describe('ExecuteQuery', () => {
 
           it('should save the state', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.save_state).toHaveBeenCalledWith(
+              expect(sqlEditorMock.saveState).toHaveBeenCalledWith(
                 'execute',
                 ['']
               );
@@ -1499,7 +1499,7 @@ describe('ExecuteQuery', () => {
 
           it('should display pga login', () => {
             setTimeout(() => {
-              expect(userManagementMock.pga_login).toHaveBeenCalled();
+              expect(userManagementMock.pgaLogin).toHaveBeenCalled();
             }, 0);
           });
         });
@@ -1561,19 +1561,19 @@ describe('ExecuteQuery', () => {
 
           it('should not save the state', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.save_state).not.toHaveBeenCalled();
+              expect(sqlEditorMock.saveState).not.toHaveBeenCalled();
             }, 0);
           });
 
           it('should not display pga login', () => {
             setTimeout(() => {
-              expect(userManagementMock.pga_login).not.toHaveBeenCalled();
+              expect(userManagementMock.pgaLogin).not.toHaveBeenCalled();
             }, 0);
           });
 
           it('should not initialize a new transaction', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.init_transaction).not.toHaveBeenCalled();
+              expect(sqlEditorMock.initTransaction).not.toHaveBeenCalled();
             }, 0);
           });
         });
@@ -1635,7 +1635,7 @@ describe('ExecuteQuery', () => {
 
           it('should save the state', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.save_state).toHaveBeenCalledWith(
+              expect(sqlEditorMock.saveState).toHaveBeenCalledWith(
                 'execute',
                 ['']
               );
@@ -1644,13 +1644,13 @@ describe('ExecuteQuery', () => {
 
           it('should not display pga login', () => {
             setTimeout(() => {
-              expect(userManagementMock.pga_login).not.toHaveBeenCalled();
+              expect(userManagementMock.pgaLogin).not.toHaveBeenCalled();
             }, 0);
           });
 
           it('should initialize a new transaction', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.init_transaction).toHaveBeenCalled();
+              expect(sqlEditorMock.initTransaction).toHaveBeenCalled();
             }, 0);
           });
         });
@@ -1665,7 +1665,7 @@ describe('ExecuteQuery', () => {
 
           it('saves state', () => {
             setTimeout(() => {
-              expect(sqlEditorMock.save_state).toHaveBeenCalledWith(
+              expect(sqlEditorMock.saveState).toHaveBeenCalledWith(
                 'execute',
                 ['']
               );
diff --git a/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js b/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
deleted file mode 100644
index 97d1bc5..0000000
--- a/web/regression/javascript/sqleditor/is_new_transaction_required_spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2018, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import {is_new_transaction_required} from '../../../pgadmin/static/js/sqleditor/is_new_transaction_required';
-
-describe('#is_new_transaction_required', () => {
-  describe('when status is not 404', () => {
-    it('should return false', () => {
-      expect(is_new_transaction_required({
-        status: 300,
-      })).toBe(false);
-    });
-  });
-
-  describe('when status is 404', () => {
-    describe('when data is not present', () => {
-      it('should return false', () => {
-        expect(is_new_transaction_required({
-          status: 404,
-        })).toBeFalsy();
-      });
-    });
-
-    describe('when data is present', () => {
-      describe('when info is not present inside data', () => {
-        it('should return false', () => {
-          expect(is_new_transaction_required({
-            status: 404,
-            data: {},
-          })).toBeFalsy();
-        });
-      });
-
-      describe('when info is present inside data', () => {
-        describe('when info value is not "DATAGRID_TRANSACTION_REQUIRED"', () => {
-          it('should return false', () => {
-            expect(is_new_transaction_required({
-              status: 404,
-              data: {
-                info: 'some information',
-              },
-            })).toBe(false);
-          });
-        });
-
-        describe('when info value is "DATAGRID_TRANSACTION_REQUIRED"', () => {
-          it('should return false', () => {
-            expect(is_new_transaction_required({
-              status: 404,
-              data: {
-                info: 'DATAGRID_TRANSACTION_REQUIRED',
-              },
-            })).toBe(true);
-          });
-        });
-      });
-    });
-  });
-});
diff --git a/web/regression/javascript/sqleditor/query_tool_http_error_handler_spec.js b/web/regression/javascript/sqleditor/query_tool_http_error_handler_spec.js
new file mode 100644
index 0000000..2128152
--- /dev/null
+++ b/web/regression/javascript/sqleditor/query_tool_http_error_handler_spec.js
@@ -0,0 +1,191 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2018, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////////////////
+
+import {
+  httpResponseRequiresNewTransaction,
+  handleQueryToolAjaxError
+} from '../../../pgadmin/static/js/sqleditor/query_tool_http_error_handler';
+
+describe('#httpResponseRequiresNewTransaction', () => {
+  describe('when status is not 404', () => {
+    it('should return false', () => {
+      expect(httpResponseRequiresNewTransaction({
+        status: 300,
+      })).toBe(false);
+    });
+  });
+
+  describe('when status is 404', () => {
+    describe('when data is not present', () => {
+      it('should return false', () => {
+        expect(httpResponseRequiresNewTransaction({
+          status: 404,
+        })).toBeFalsy();
+      });
+    });
+
+    describe('when data is present', () => {
+      describe('when info is not present inside data', () => {
+        it('should return false', () => {
+          expect(httpResponseRequiresNewTransaction({
+            status: 404,
+            data: {},
+          })).toBeFalsy();
+        });
+      });
+
+      describe('when info is present inside data', () => {
+        describe('when info value is not "DATAGRID_TRANSACTION_REQUIRED"', () => {
+          it('should return false', () => {
+            expect(httpResponseRequiresNewTransaction({
+              status: 404,
+              data: {
+                info: 'some information',
+              },
+            })).toBe(false);
+          });
+        });
+
+        describe('when info value is "DATAGRID_TRANSACTION_REQUIRED"', () => {
+          it('should return false', () => {
+            expect(httpResponseRequiresNewTransaction({
+              status: 404,
+              data: {
+                info: 'DATAGRID_TRANSACTION_REQUIRED',
+              },
+            })).toBe(true);
+          });
+        });
+      });
+    });
+  });
+});
+
+
+describe('#handleQueryToolAjaxError', () => {
+  let sqlEditorHandler,
+    exceptionSpy, stateToSave,
+    stateParameters, checkTransaction, UserManagementMock,
+    pgBrowserMock;
+
+    beforeEach(() => {
+      stateToSave = 'testState';
+      stateParameters = [];
+      checkTransaction = false;
+      sqlEditorHandler = jasmine.createSpyObj(
+        'handler', ['initTransaction', 'saveState', 'handle_connection_lost']
+      );
+      exceptionSpy = {
+        readyState: 0,
+        status: 404,
+        data: {
+          info: 'CONNECTION_LOST',
+        },
+      };
+      pgBrowserMock = {
+        'Browser': {
+          'UserManagement': jasmine.createSpyObj('UserManagement', ['isPgaLoginRequired', 'pgaLogin'])
+        }
+      };
+    });
+
+  describe('when ready state is 0', () => {
+    it('should return connection', () => {
+      expect(
+        handleQueryToolAjaxError(
+          pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
+          stateParameters, checkTransaction
+        )
+      ).toBe('Not connected to the server or the connection to the server has been closed.');
+    });
+  });
+
+  describe('when there is an ajax error due to login is required', () => {
+    beforeEach(() => {
+      exceptionSpy.readyState = 1;
+      exceptionSpy.status = 401;
+      exceptionSpy.data.info = 'PGADMIN_LOGIN_REQUIRED';
+      pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(true);
+    });
+
+    it('should save the current state and call login handler', () => {
+      handleQueryToolAjaxError(
+        pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
+        stateParameters, checkTransaction
+      );
+      expect(sqlEditorHandler.saveState).toHaveBeenCalledWith(stateToSave, stateParameters);
+      expect(pgBrowserMock.Browser.UserManagement.pgaLogin).toHaveBeenCalled();
+    });
+  });
+
+  describe('when there is an ajax error and new transaction initialization required', () => {
+    beforeEach(() => {
+      exceptionSpy.readyState = 1;
+      exceptionSpy.status = 404;
+      exceptionSpy.data.info = 'DATAGRID_TRANSACTION_REQUIRED';
+      pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(false);
+      checkTransaction = true;
+    });
+
+    it('should save the current state and call login handler', () => {
+      handleQueryToolAjaxError(
+        pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
+        stateParameters, checkTransaction
+      );
+      expect(pgBrowserMock.Browser.UserManagement.pgaLogin).not.toHaveBeenCalled();
+      expect(sqlEditorHandler.saveState).toHaveBeenCalledWith(stateToSave, stateParameters);
+      expect(sqlEditorHandler.initTransaction).toHaveBeenCalled();
+    });
+  });
+
+  describe('when there is an ajax error due to database connection has been lost', () => {
+    beforeEach(() => {
+      exceptionSpy.readyState = 1;
+      exceptionSpy.status = 503;
+      exceptionSpy.responseJSON = {
+        'info': 'CONNECTION_LOST'
+      };
+      pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(false);
+      checkTransaction = false;
+    });
+
+    it('should save the current state and call connection lost handler', (done) => {
+      handleQueryToolAjaxError(
+        pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
+        stateParameters, checkTransaction
+      );
+      expect(pgBrowserMock.Browser.UserManagement.pgaLogin).not.toHaveBeenCalled();
+      setTimeout(() => {
+        expect(sqlEditorHandler.saveState).toHaveBeenCalledWith(stateToSave, stateParameters);
+        expect(sqlEditorHandler.handle_connection_lost).toHaveBeenCalledWith(false, exceptionSpy);
+        done();
+      }, 0);
+    });
+  });
+
+  describe('when there is an ajax error due to unknown reason', () => {
+    beforeEach(() => {
+      exceptionSpy.readyState = 1;
+      exceptionSpy.status = 803;
+      exceptionSpy.responseText = 'ajax failed with unknown reason';
+      pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(false);
+      checkTransaction = false;
+    });
+
+    it('should return proper error message from ajax exception', () => {
+      expect(
+        handleQueryToolAjaxError(
+          pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
+          stateParameters, checkTransaction
+        )
+      ).toBe('ajax failed with unknown reason');
+    });
+  });
+
+});


view thread (6+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected]
  Subject: Re: [pgAdmin4][RM#3235] Code refactoring in Query tool
  In-Reply-To: <CAKKotZS5pAJ70iNJkvUTLr5jZ7nJNArwkiQyfgaz3y9csdarWg@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox