From b73a8d10b2caf5f40bd354beb5c109b57ef7ad35 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Tue, 17 Sep 2013 10:58:12 +0200 Subject: [PATCH] smoother handling of when backend cannot be reached at all --- auth/manifoldbackend.py | 6 ++++-- manifold/manifoldapi.py | 9 ++++++--- manifold/manifoldresult.py | 10 +++++++--- portal/homeview.py | 18 ++++++++++++++++-- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/auth/manifoldbackend.py b/auth/manifoldbackend.py index 529ef0fc..14abb748 100644 --- a/auth/manifoldbackend.py +++ b/auth/manifoldbackend.py @@ -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 diff --git a/manifold/manifoldapi.py b/manifold/manifoldapi.py index 8d4d1ac0..3f4bd10e 100644 --- a/manifold/manifoldapi.py +++ b/manifold/manifoldapi.py @@ -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'] diff --git a/manifold/manifoldresult.py b/manifold/manifoldresult.py index a20c5b03..dcf1a2e8 100644 --- a/manifold/manifoldresult.py +++ b/manifold/manifoldresult.py @@ -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() diff --git a/portal/homeview.py b/portal/homeview.py index a66cd36d..fb012402 100644 --- a/portal/homeview.py +++ b/portal/homeview.py @@ -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)) -- 2.43.0