Commit 8fb812e4 authored by Romain Loth's avatar Romain Loth

[MSG OK] better error handling between server-side graph generation and the...

[MSG OK] better error handling between server-side graph generation and the error messages shown on client-side
parent 153ed4ef
...@@ -78,17 +78,25 @@ def get_graph( request=None , corpus=None ...@@ -78,17 +78,25 @@ def get_graph( request=None , corpus=None
after_cooc = datetime.now() after_cooc = datetime.now()
print("... Cooccurrences took %f s." % (after_cooc - before_cooc).total_seconds()) print("... Cooccurrences took %f s." % (after_cooc - before_cooc).total_seconds())
G, partition, ids, weight = clusterByDistances ( cooc_matrix
, field1="ngrams", field2="ngrams"
, distance=distance
)
after_cluster = datetime.now() # case when 0 coocs are observed (usually b/c not enough ngrams in maplist)
print("... Clustering took %f s." % (after_cluster - after_cooc).total_seconds()) if len(cooc_matrix.items) == 0:
print("GET_GRAPH: 0 coocs in matrix")
data = {'nodes':[], 'links':[]} # empty data
data = filterByBridgeness(G,partition,ids,weight,bridgeness,type,field1,field2) # normal case
else:
G, partition, ids, weight = clusterByDistances ( cooc_matrix
, field1="ngrams", field2="ngrams"
, distance=distance
)
after_cluster = datetime.now()
print("... Clustering took %f s." % (after_cluster - after_cooc).total_seconds())
data = filterByBridgeness(G,partition,ids,weight,bridgeness,type,field1,field2)
after_filter = datetime.now() after_filter = datetime.now()
print("... Filtering took %f s." % (after_filter - after_cluster).total_seconds()) print("... Filtering took %f s." % (after_filter - after_cluster).total_seconds())
return data return data
...@@ -6,6 +6,8 @@ from graph.graph import get_graph ...@@ -6,6 +6,8 @@ from graph.graph import get_graph
from gargantext.util.http import APIView, APIException\ from gargantext.util.http import APIView, APIException\
, JsonHttpResponse, requires_auth , JsonHttpResponse, requires_auth
from traceback import format_tb
# TODO check authentication # TODO check authentication
class Graph(APIView): class Graph(APIView):
...@@ -19,28 +21,28 @@ class Graph(APIView): ...@@ -19,28 +21,28 @@ class Graph(APIView):
graph?field1=ngrams&field2=ngrams& graph?field1=ngrams&field2=ngrams&
graph?field1=ngrams&field2=ngrams&start=''&end='' graph?field1=ngrams&field2=ngrams&start=''&end=''
''' '''
# Get the node we are working with # Get the node we are working with
corpus = session.query(Node).filter(Node.id==corpus_id).first() corpus = session.query(Node).filter(Node.id==corpus_id).first()
# Get all the parameters in the URL # Get all the parameters in the URL
cooc_id = request.GET.get ('cooc_id' , None ) cooc_id = request.GET.get ('cooc_id' , None )
field1 = str(request.GET.get ('field1' , 'ngrams' )) field1 = str(request.GET.get ('field1' , 'ngrams' ))
field2 = str(request.GET.get ('field2' , 'ngrams' )) field2 = str(request.GET.get ('field2' , 'ngrams' ))
start = request.GET.get ('start' , None ) start = request.GET.get ('start' , None )
end = request.GET.get ('end' , None ) end = request.GET.get ('end' , None )
mapList_id = int(request.GET.get ('mapList' , 0 )) mapList_id = int(request.GET.get ('mapList' , 0 ))
groupList_id = int(request.GET.get ('groupList' , 0 )) groupList_id = int(request.GET.get ('groupList' , 0 ))
threshold = int(request.GET.get ('threshold' , 1 )) threshold = int(request.GET.get ('threshold' , 1 ))
bridgeness = int(request.GET.get ('bridgeness', -1 )) bridgeness = int(request.GET.get ('bridgeness', -1 ))
format_ = str(request.GET.get ('format' , 'json' )) format_ = str(request.GET.get ('format' , 'json' ))
type_ = str(request.GET.get ('type' , 'node_link' )) type_ = str(request.GET.get ('type' , 'node_link' ))
distance = str(request.GET.get ('distance' , 'conditional')) distance = str(request.GET.get ('distance' , 'conditional'))
# Get default value if no map list # Get default value if no map list
if mapList_id == 0 : if mapList_id == 0 :
...@@ -50,10 +52,11 @@ class Graph(APIView): ...@@ -50,10 +52,11 @@ class Graph(APIView):
) )
.first() .first()
) )
mapList_id = mapList_id[0] mapList_id = mapList_id[0]
if mapList_id == None : if mapList_id == None :
# todo add as an error msg ?
raise ValueError("MAPLIST node needed for cooccurrences") raise ValueError("MAPLIST node needed for cooccurrences")
...@@ -65,23 +68,23 @@ class Graph(APIView): ...@@ -65,23 +68,23 @@ class Graph(APIView):
) )
.first() .first()
) )
groupList_id = groupList_id[0] groupList_id = groupList_id[0]
if groupList_id == None : if groupList_id == None :
# todo add as an error msg ?
raise ValueError("GROUPLIST node needed for cooccurrences") raise ValueError("GROUPLIST node needed for cooccurrences")
# Chec the options # Check the options
accepted_field1 = ['ngrams', 'journal', 'source', 'authors'] accepted_field1 = ['ngrams', 'journal', 'source', 'authors']
accepted_field2 = ['ngrams', ] accepted_field2 = ['ngrams', ]
options = ['start', 'end', 'threshold', 'distance', 'cooc_id' ] options = ['start', 'end', 'threshold', 'distance', 'cooc_id' ]
# Test function
if field1 in accepted_field1 :
if field2 in accepted_field2 : try:
# Test params
if (field1 in accepted_field1) and (field2 in accepted_field2):
if start is not None and end is not None : if start is not None and end is not None :
data = get_graph( corpus=corpus, cooc_id = cooc_id data = get_graph( corpus=corpus, cooc_id = cooc_id
#, field1=field1 , field2=field2 #, field1=field1 , field2=field2
...@@ -97,12 +100,31 @@ class Graph(APIView): ...@@ -97,12 +100,31 @@ class Graph(APIView):
, distance = distance , distance = distance
, bridgeness = bridgeness , bridgeness = bridgeness
) )
if format_ == 'json': # Test data length
return JsonHttpResponse(data) if len(data['nodes']) > 0 and len(data['links']) > 0:
else: # normal case --------------------------------
if format_ == 'json':
return JsonHttpResponse(data, status=200)
# --------------------------------------------
else:
# empty data case
return JsonHttpResponse({
'msg': '''Empty graph warning
No cooccurences found in this corpus for the words of this maplist
(maybe add more terms to the maplist?)''',
}, status=400)
else:
# parameters error case
return JsonHttpResponse({
'msg': '''Usage warning
Please choose only one field from each range:
- "field1": %s
- "field2": %s
- "options": %s''' % (accepted_field1, accepted_field2, options)
}, status=400)
# for any other errors that we forgot to test
except Exception as e:
return JsonHttpResponse({ return JsonHttpResponse({
'Warning USAGE' : 'One field for each range:' 'msg' : 'Unknown error (showing the trace):\n%s' % "\n".join(format_tb(e.__traceback__))
, 'field1' : accepted_field1 }, status=400)
, 'field2' : accepted_field2
, 'options': options
})
...@@ -357,6 +357,27 @@ ...@@ -357,6 +357,27 @@
</div> </div>
</div> </div>
<div id="errormodal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Graph generation error</h4>
</div>
<div class="modal-body form-horizontal">
<div id="errormsg"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
<div id="modalloader" class="modal fade"> <div id="modalloader" class="modal fade">
<div id="loader" class="loader"> <div id="loader" class="loader">
......
...@@ -76,25 +76,32 @@ $.ajax({ ...@@ -76,25 +76,32 @@ $.ajax({
success : function(data, textStatus, jqXHR) { success : function(data, textStatus, jqXHR) {
header = jqXHR.getResponseHeader("Content-Type") header = jqXHR.getResponseHeader("Content-Type")
header = (header)?"json":"gexf"; header = (header)?"json":"gexf";
Result = { "OK":true , "format":header , "data":data }; Result = { "format":header , "data":data };
MainFunction( Result ) MainFunction( Result )
}, },
error: function(exception) { error: function(exception) {
Result = { "OK":false , "format":false , "data":exception.status }; // console.warn(JSON.stringify(exception, null, 2))
MainFunction( Result ) showErrorDialog(file, exception.status, exception.responseJSON.msg)
} }
}); });
function showErrorDialog(url, status, msg) {
console.log('FUN t.main:showErrorDialog')
// hide loader gif etc
$("#semLoader").hide();
$("#closeloader").click();
// copy message content
$('#errormsg').html(msg.replace(/\n/g, '<br/>'))
// show the dialog box
$('#errormodal').modal('show');
}
function MainFunction( RES ) { function MainFunction( RES ) {
console.log(' ------------') console.log(' ------------')
console.log('FUN t.main:MainFunction') console.log('FUN t.main:MainFunction')
console.log(' ------------') console.log(' ------------')
if(!RES["OK"]) {
alert("error: "+RES["data"])
return false;
}
var fileparam;// = { db|api.json , somefile.json|gexf } var fileparam;// = { db|api.json , somefile.json|gexf }
var the_data = RES["data"]; var the_data = RES["data"];
......
...@@ -362,7 +362,26 @@ ...@@ -362,7 +362,26 @@
</div> </div>
</div> </div>
<div id="errormodal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Graph generation error</h4>
</div>
<div class="modal-body form-horizontal">
<div id="errormsg"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
<div id="corpuses" class="modal fade"> <div id="corpuses" class="modal fade">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment