Browse Source

HUE-1833 [spark] Gracefully fail when the server is not up

Added error page and exception catching on API
Enrico Berti 12 years ago
parent
commit
24cf3bf

+ 6 - 19
apps/spark/src/spark/api.py

@@ -33,24 +33,11 @@ from desktop.lib.i18n import smart_str
 from spark.design import SparkDesign
 from desktop.lib.rest.http_client import RestException
 
+from spark.decorators import json_error_handler
 
 LOG = logging.getLogger(__name__)
 
-
-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
-
-
+@json_error_handler
 def jars(request):
   api = get_api(request.user)
   response = {
@@ -59,7 +46,7 @@ def jars(request):
 
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
-
+@json_error_handler
 def contexts(request):
   api = get_api(request.user)
   response = {
@@ -125,7 +112,7 @@ def job(request, job_id):
 
 
 
-@error_handler
+@json_error_handler
 def execute(request, design_id=None):
   response = {'status': -1, 'message': ''}
 
@@ -180,7 +167,7 @@ def execute(request, design_id=None):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
-@error_handler
+@json_error_handler
 def save_query(request, design_id=None):
   response = {'status': -1, 'message': ''}
 
@@ -210,7 +197,7 @@ def save_query(request, design_id=None):
   return HttpResponse(json.dumps(response), mimetype="application/json")
 
 
-@error_handler
+@json_error_handler
 def fetch_saved_query(request, design_id):
   response = {'status': -1, 'message': ''}
 

+ 49 - 0
apps/spark/src/spark/decorators.py

@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. 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 json
+import logging
+
+from django.http import HttpResponse, Http404
+from django.utils.translation import ugettext as _
+from desktop.lib.exceptions_renderable import PopupException
+
+LOG = logging.getLogger(__name__)
+
+def view_error_handler(view_fn):
+  def decorator(*args, **kwargs):
+    try:
+      return view_fn(*args, **kwargs)
+    except Http404, e:
+      raise e
+    except Exception, e:
+      raise PopupException(_('An error happened with the Spark Server'), detail=e)
+  return decorator
+
+
+def json_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

+ 11 - 6
apps/spark/src/spark/views.py

@@ -32,13 +32,18 @@ from beeswax.views import safe_get_design
 from spark.job_server_api import get_api
 from spark.forms import UploadApp
 from desktop.lib.exceptions import StructuredException
+from desktop.lib.rest.http_client import RestException
 from spark.api import design_to_dict
 
+from spark.decorators import view_error_handler
 
-LOG = logging.getLogger(__name__)
 
+LOG = logging.getLogger(__name__)
 
+@view_error_handler
 def editor(request, design_id=None):
+  api = get_api(request.user)
+  jobs = api.jobs()
   if design_id is not None and not design_id.isdigit():
     job_id, design_id = design_id, None
   else:
@@ -57,7 +62,7 @@ def editor(request, design_id=None):
     'job_id': job_id,
   })
 
-
+@view_error_handler
 def list_jobs(request):
   api = get_api(request.user)
   jobs = api.jobs()
@@ -67,7 +72,7 @@ def list_jobs(request):
     'jobs_json': json.dumps(jobs)
   })
 
-
+@view_error_handler
 def list_contexts(request):
   api = get_api(request.user)
   contexts = api.contexts()
@@ -77,7 +82,7 @@ def list_contexts(request):
     'contexts_json': json.dumps(contexts)
   })
 
-
+@view_error_handler
 def delete_contexts(request):
   if request.method == 'POST':
     api = get_api(request.user)
@@ -88,7 +93,7 @@ def delete_contexts(request):
   else:
     return render('confirm.mako', request, {'url': request.path, 'title': _('Delete context(s)?')})
 
-
+@view_error_handler
 def list_applications(request):
   api = get_api(request.user)
   applications = api.jars()
@@ -123,7 +128,7 @@ def upload_app(request):
 
   return redirect(request.META['HTTP_REFERER'])
 
-
+@view_error_handler
 def download_result(request, job_id):
   api = get_api(request.user)
   result = api.job(job_id)

+ 12 - 2
apps/spark/static/js/spark.vm.js

@@ -303,7 +303,12 @@ function sparkViewModel() {
       dataType: 'json',
       type: 'GET',
       success: function(data) {
-        self.updateAppNames(data.jars);
+        if (data.error != null) {
+          $.jHueNotify.error(data.error);
+        }
+        else {
+          self.updateAppNames(data.jars);
+        }
       },
       error: error_fn
     };
@@ -316,7 +321,12 @@ function sparkViewModel() {
       dataType: 'json',
       type: 'GET',
       success: function(data) {
-        self.updateContexts(data.contexts);
+        if (data.error != null) {
+          $.jHueNotify.error(data.error);
+        }
+        else {
+          self.updateContexts(data.contexts);
+        }
       },
       error: error_fn
     };