smoother handling of when backend cannot be reached at all
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Tue, 17 Sep 2013 08:58:12 +0000 (10:58 +0200)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Tue, 17 Sep 2013 08:58:12 +0000 (10:58 +0200)
auth/manifoldbackend.py
manifold/manifoldapi.py
manifold/manifoldresult.py
portal/homeview.py

index 529ef0f..14abb74 100644 (file)
@@ -2,7 +2,7 @@ import time
 
 from django.contrib.auth.models import User
 
-from manifold.manifoldapi import ManifoldAPI, ManifoldResult
+from manifold.manifoldapi import ManifoldAPI, ManifoldException, ManifoldResult
 from manifold.core.query        import Query
 
 # Name my backend 'ManifoldBackend'
@@ -30,7 +30,6 @@ class ManifoldBackend:
                 return
             print "first", sessions
             session = sessions[0]
-            print "SESSION=", session
 
             # Change to session authentication
             api.auth = {'AuthMethod': 'session', 'session': session['session']}
@@ -47,6 +46,9 @@ class ManifoldBackend:
             print "PERSON=", person
 
             request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
+        except ManifoldException, e:
+            print "Caught ManifoldException, returning corresponding ManifoldResult"
+            return e.manifold_result
         except Exception, e:
             print "E: manifoldbackend", e
             import traceback
index 8d4d1ac..3f4bd10 100644 (file)
@@ -65,8 +65,11 @@ class ManifoldAPI:
                 return ResultValue(**result)
 
             except Exception,error:
-                # XXX Connection refused for example
-                print "** API ERROR **"
+                if "Connection refused" in error:
+                    raise ManifoldException ( ManifoldResult (code=ManifoldCode.SERVER_UNREACHABLE,
+                                                              output="%s answered %s"%(self.url,error)))
+                # otherwise
+                print "** MANIFOLD API ERROR **"
                 import traceback
                 traceback.print_exc()
                 if debug: print "KO (unexpected exception)",error
@@ -76,7 +79,7 @@ class ManifoldAPI:
 
 def execute_query(request, query):
     if not 'manifold' in request.session or not 'auth' in request.session['manifold']:
-        print "W: Used hardcoded demo account for execute_query"
+        print "W: Using hardcoded demo account for execute_query"
         manifold_api_session_auth = {'AuthMethod': 'password', 'Username': 'demo', 'AuthString': 'demo'}
     else:
         manifold_api_session_auth = request.session['manifold']['auth']
index a20c5b0..dcf1a2e 100644 (file)
@@ -3,12 +3,15 @@ def enum(*sequential, **named):
     return type('Enum', (), enums)
 
 ManifoldCode = enum (
+    UNKNOWN_ERROR=-1,
     SUCCESS=0,
     SESSION_EXPIRED=1,
     NOT_IMPLEMENTED=2,
-    UNKNOWN_ERROR=3,
+    SERVER_UNREACHABLE=3,
 )
 
+_messages_ = { -1 : "Unknown", 0: "OK", 1: "Session Expired", 2: "Not Implemented", 3: "Backend server unreachable"}
+
 # being a dict this can be used with json.dumps
 class ManifoldResult (dict):
     def __init__ (self, code=ManifoldCode.SUCCESS, value=None, output=""):
@@ -37,8 +40,9 @@ class ManifoldResult (dict):
     
 
     def __repr__ (self):
-        result="[[MFresult code=%s"%self['code']
-        if self['code']==0:
+        code=self['code']
+        result="[[MFresult %s (code=%s)"%(_messages_.get(code,"???"),code)
+        if code==0:
             value=self['value']
             if isinstance(value,list): result += " [value=list with %d elts]"%len(value)
             elif isinstance(value,dict): result += " [value=dict with keys %s]"%value.keys()
index a66cd36..fb01240 100644 (file)
@@ -6,6 +6,7 @@ from django.contrib.auth import authenticate, login, logout
 from django.template import RequestContext
 from django.shortcuts import render_to_response
 
+from manifold.manifoldresult import ManifoldResult
 from myslice.viewutils import topmenu_items, the_user
 from myslice.config import Config
 
@@ -24,8 +25,20 @@ class HomeView (View):
         # pass request within the token, so manifold session key can be attached to the request session.
         token = {'username': username, 'password': password, 'request': request}    
 
-        user = authenticate(token=token)
-        if user is not None:
+        # our authenticate function returns either
+        # . a ManifoldResult - when something has gone wrong, like e.g. backend is unreachable
+        # . a django User in case of success
+        # . or None if the backend could be reached but the authentication failed
+        auth_result = authenticate(token=token)
+        # high-level errors, like connection refused or the like
+        if isinstance (auth_result, ManifoldResult):
+            manifoldresult = auth_result
+            # let's use ManifoldResult.__repr__
+            env['state']="%s"%manifoldresult
+            return render_to_response('home-view.html',env, context_instance=RequestContext(request))
+        # user was authenticated at the backend
+        elif auth_result is not None:
+            user=auth_result
             if user.is_active:
                 print "LOGGING IN"
                 login(request, user)
@@ -33,6 +46,7 @@ class HomeView (View):
             else:
                 env['state'] = "Your account is not active, please contact the site admin."
                 return render_to_response('home-view.html',env, context_instance=RequestContext(request))
+        # otherwise
         else:
             env['state'] = "Your username and/or password were incorrect."
             return render_to_response('home-view.html',env, context_instance=RequestContext(request))