瀏覽代碼

HUE-1762 [dbquery] Show errors in the UI in case of DB connection failure

Added an error decorator for APIs that catches all exceptions
and forms a JSON response with an error message.
Abraham Elmahrek 12 年之前
父節點
當前提交
51d2ce3619
共有 3 個文件被更改,包括 45 次插入6 次删除
  1. 24 1
      apps/rdbms/src/rdbms/api.py
  2. 8 0
      apps/rdbms/src/rdbms/templates/execute.mako
  3. 13 5
      apps/rdbms/static/js/rdbms.vm.js

+ 24 - 1
apps/rdbms/src/rdbms/api.py

@@ -45,6 +45,20 @@ class ResultEncoder(json.JSONEncoder):
     return super(ResultEncoder, self).default(obj)
 
 
+def error_handler(view_fn):
+  def decorator(*args, **kwargs):
+    try:
+      return view_fn(*args, **kwargs)
+    except Http404, e:
+      raise e
+    except Exception, e:
+      response = {
+        'error': str(e)
+      }
+      return HttpResponse(json.dumps(response), mimetype="application/json", status=500)
+  return decorator
+
+
 def servers(request):
   servers = conf.get_server_choices()
   servers_dict = dict(servers)
@@ -55,21 +69,24 @@ def servers(request):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def databases(request, server):
   query_server = dbms.get_query_server_config(server)
 
   if not query_server:
     raise Http404
-  
+
   db = dbms.get(request.user, query_server)
 
   response = {
+    'status': 0,
     'databases': db.get_databases()
   }
 
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def tables(request, server, database):
   query_server = dbms.get_query_server_config(server)
 
@@ -86,6 +103,7 @@ def tables(request, server, database):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def columns(request, server, database, table):
   query_server = dbms.get_query_server_config(server)
 
@@ -102,6 +120,7 @@ def columns(request, server, database, table):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def execute_query(request, design_id=None):
   response = {'status': -1, 'message': ''}
 
@@ -146,6 +165,7 @@ def execute_query(request, design_id=None):
   return HttpResponse(json.dumps(response, cls=ResultEncoder), mimetype="application/json")
 
 
+@error_handler
 def explain_query(request):
   response = {'status': -1, 'message': ''}
 
@@ -183,6 +203,7 @@ def explain_query(request):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def fetch_results(request, id, first_row=0):
   """
   Returns the results of the QueryHistory with the given id.
@@ -227,6 +248,7 @@ def fetch_results(request, id, first_row=0):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def save_query(request, design_id=None):
   response = {'status': -1, 'message': ''}
 
@@ -253,6 +275,7 @@ def save_query(request, design_id=None):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
+@error_handler
 def fetch_saved_query(request, design_id):
   response = {'status': -1, 'message': ''}
 

+ 8 - 0
apps/rdbms/src/rdbms/templates/execute.mako

@@ -758,6 +758,14 @@ ${ commonheader(_('Query'), app_name, user) | n,unicode }
   $(document).on('executed.query', resultsTable);
   $(document).on('explained.query', resultsTable);
 
+  // Server error handling.
+  $(document).on('server.error', function(e, data) {
+    $(document).trigger('error', "${_('Server error occured: ')}" + data.error);
+  });
+  $(document).on('server.unmanageable_error', function(e, responseText) {
+    $(document).trigger('error', "${_('Unmanageable server error occured: ')}" + responseText);
+  });
+
 </script>
 
 ${ commonfooter(messages) | n,unicode }

+ 13 - 5
apps/rdbms/static/js/rdbms.vm.js

@@ -140,6 +140,14 @@ function RdbmsViewModel() {
     $.totalStorage(key, value);
   };
 
+  var error_fn = function(jqXHR, status, errorThrown) {
+    try {
+      $(document).trigger('server.error', $.parseJSON(jqXHR.responseText));
+    } catch(e) {
+      $(document).trigger('server.unmanageable_error', jqXHR.responseText);
+    }
+  };
+
   self.explainQuery = function() {
     var data = ko.mapping.toJS(self.query);
     data.database = self.database();
@@ -160,7 +168,7 @@ function RdbmsViewModel() {
           self.query.errors.push(data.message);
         }
       },
-      error: $.noop,
+      error: error_fn,
       data: data
     };
     $.ajax(request);
@@ -176,7 +184,7 @@ function RdbmsViewModel() {
         success: function(data) {
           self.updateQuery(data.design);
         },
-        error: $.noop
+        error: error_fn
       };
       $.ajax(request);
     }
@@ -229,7 +237,7 @@ function RdbmsViewModel() {
           self.query.errors.push(data.message);
         }
       },
-      error: $.noop,
+      error: error_fn,
       data: data
     };
     $.ajax(request);
@@ -244,7 +252,7 @@ function RdbmsViewModel() {
         self.updateServers(data.servers);
         self.fetchDatabases();
       },
-      error: $.noop
+      error: error_fn
     };
     $.ajax(request);
   };
@@ -258,7 +266,7 @@ function RdbmsViewModel() {
         success: function(data) {
           self.updateDatabases(data.databases);
         },
-        error: $.noop
+        error: error_fn
       };
       $.ajax(request);
     }