Commit 8b244558 authored by Dimitris Moraitis's avatar Dimitris Moraitis
Browse files

detailed error handling & iso8601 compatibility - Refs #213 #363

parent f3b29b98
......@@ -10,6 +10,7 @@ Synnefo depends on the following Python modules
- simplejson
- selenium
- pyzmq-static
- iso8601
also, depending on the database engine of choice, on one of the following:
- MySQL-python
......
......@@ -14,7 +14,7 @@ import random
import string
import logging
from datetime import datetime, timedelta
import iso8601
from logic import backend, utils
log = logging.getLogger('synnefo.api.handlers')
......@@ -144,10 +144,9 @@ class ServerHandler(BaseHandler):
try:
changes_since = request.GET.get("changes-since", 0)
if changes_since:
last_update = datetime.strptime(changes_since,
"%Y-%m-%dT%H:%M:%S")
last_update = iso8601.parse_date(changes_since)
#return a badRequest if the changes_since is older than a limit
if (datetime.now() - last_update >
if (datetime.now(last_update.tzinfo) - last_update >
timedelta(seconds=settings.POLL_LIMIT)):
raise fault.badRequest
virtual_servers = VirtualMachine.objects.filter(
......
......@@ -531,7 +531,7 @@ div.machine div.actions a.more {
margin-top: 18px;
}
div.actions a:hover{
div.actions a.enabled:hover{
color: black !important;
text-decoration: underline;
display: block;
......@@ -850,6 +850,12 @@ input.machine {
color: #F49C1A;
}
#error-success div {
height: 142px;
overflow-y: auto;
overflow-x: hidden;
}
#error-success .close {
background-image: url(/static/close.png);
position: absolute;
......@@ -1163,7 +1169,7 @@ div.actions a.selected, div.actions a.selected:hover {
color: orange !important;
}
.message {
.action_error .message, .action_error .code {
display: none;
}
......
......@@ -11,8 +11,18 @@ function ISODateString(d){
pad(d.getUTCMonth()+1) + '-' +
pad(d.getUTCDate()) + 'T' +
pad(d.getUTCHours()) + ':' +
pad(d.getUTCMinutes())+ ':' +
pad(d.getUTCSeconds())
pad(d.getUTCMinutes()) + ':' +
pad(d.getUTCSeconds()) +'Z'
}
function parse_error(responseText){
var errors = [];
responseObj = JSON.parse(responseText);
//console.info(inp);
for (var err in responseObj){
errors[errors.length] = responseObj[err];
}
return errors;
}
// indexOf prototype for IE
......@@ -221,7 +231,7 @@ function update_vms(interval) {
}
// as for now, just show an error message
try { console.info('update_vms errback:' + jqXHR.status ) } catch(err) {}
ajax_error(jqXHR.status);
ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);
return false;
},
success: function(data, textStatus, jqXHR) {
......@@ -239,11 +249,11 @@ function update_vms(interval) {
if (jqXHR.status == 200 || jqXHR.status == 203) {
try {
servers = data.servers;
} catch(err) { ajax_error('400');}
} catch(err) { ajax_error('400', undefined, 'Update VMs', jqXHR.responseText);}
update_machines_view(data);
} else if (jqXHR.status != 304){
try { console.info('update_vms callback:' + jqXHR.status ) } catch(err) {}
//ajax_error();
//ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);
}
return false;
}
......@@ -260,7 +270,7 @@ function update_images() {
dataType: "json",
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
ajax_error(jqXHR.status);
ajax_error(jqXHR.status, undefined, 'Update Images', jqXHR.responseText);
},
success: function(data, textStatus, jqXHR) {
try {
......@@ -365,7 +375,7 @@ function update_flavors() {
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
try {
ajax_error(jqXHR.status);
ajax_error(jqXHR.status, undefined, 'Update Flavors', jqXHR.responseText);
} catch (err) {
ajax_error(err);
}
......@@ -447,7 +457,7 @@ function create_vm(machineName, imageRef, flavorRef){
"flavorRef" : flavorRef,
"metadata" : {
"My Server Name" : machineName
},
}
}
};
......@@ -459,13 +469,13 @@ function create_vm(machineName, imageRef, flavorRef){
data: JSON.stringify(payload),
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
ajax_error(jqXHR.status);
ajax_error(jqXHR.status, undefined, 'Create VM', jqXHR.responseText);
},
success: function(data, textStatus, jqXHR) {
if ( jqXHR.status == '202') {
ajax_success("CREATE_VM_SUCCESS", data.server.adminPass);
} else {
ajax_error(jqXHR.status);
ajax_error(jqXHR.status, undefined, 'Create VM', jqXHR.responseText);
}
}
});
......@@ -490,7 +500,7 @@ function reboot(serverIDs){
data: JSON.stringify(payload),
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
display_failure(serverID, jqXHR.status, 'Reboot')
display_failure(jqXHR.status, serverID, 'Reboot', jqXHR.responseText)
},
success: function(data, textStatus, jqXHR) {
if ( jqXHR.status == '202') {
......@@ -502,7 +512,7 @@ function reboot(serverIDs){
// continue with the rest of the servers
reboot(serverIDs);
} else {
ajax_error(jqXHR.status, serverID);
ajax_error(jqXHR.status, serverID, 'Reboot', jqXHR.responseText);
}
}
});
......@@ -529,7 +539,7 @@ function shutdown(serverIDs) {
data: JSON.stringify(payload),
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
display_failure(serverID, jqXHR.status, 'Shutdown')
display_failure(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText)
},
success: function(data, textStatus, jqXHR) {
if ( jqXHR.status == '202') {
......@@ -541,7 +551,7 @@ function shutdown(serverIDs) {
// continue with the rest of the servers
shutdown(serverIDs);
} else {
ajax_error(jqXHR.status, serverID);
ajax_error(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText);
}
}
});
......@@ -566,7 +576,7 @@ function destroy(serverIDs) {
data: JSON.stringify(payload),
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
display_failure(serverID, jqXHR.status, 'Destroy')
display_failure(jqXHR.status, serverID, 'Destroy', jqXHR.responseText)
},
success: function(data, textStatus, jqXHR) {
if ( jqXHR.status == '204') {
......@@ -578,7 +588,7 @@ function destroy(serverIDs) {
// continue with the rest of the servers
destroy(serverIDs);
} else {
ajax_error(jqXHR.status, serverID);
ajax_error(jqXHR.status, serverID, 'Destroy', jqXHR.responseText);
}
}
});
......@@ -605,7 +615,7 @@ function start(serverIDs){
data: JSON.stringify(payload),
timeout: TIMEOUT,
error: function(jqXHR, textStatus, errorThrown) {
display_failure(serverID, jqXHR.status, 'Start')
display_failure(jqXHR.status, serverID, 'Start', jqXHR.responseText)
},
success: function(data, textStatus, jqXHR) {
if ( jqXHR.status == '202') {
......@@ -617,7 +627,7 @@ function start(serverIDs){
// continue with the rest of the servers
start(serverIDs);
} else {
ajax_error(jqXHR.status, serverID);
ajax_error(jqXHR.status, serverID, 'Start', jqXHR.responseText);
}
}
});
......
......@@ -64,15 +64,25 @@
};
// ajax error checking
function ajax_error(status, serverID) {
function ajax_error(status, serverID, action, responseText) {
var serverName = '';
if (serverID != undefined) {
serverName = $("#"+serverID).parent().parent().find("span.name").text();
}
// prepare the error message
$("#error-success h3").text(ERRORS['HEADER']);
if (ERRORS[status] != undefined) {
if (responseText != undefined){
var errors = parse_error(responseText);
if (serverName){
serverName="<p><strong>Server:</strong> " + serverName + "</p>";
}
$("#error-success div").html("<p>"+(errors[0].message || ERRORS[errors[0].code]) +"</p>"+serverName +"<p><strong>Action:</strong> " + action + "</p><p><strong>Code</strong>: " + errors[0].code + "</p><p><strong>Details:</strong> " + errors[0].details +"</p>");
} else if (ERRORS[status] != undefined) {
if (serverID == undefined){
$("#error-success p").text(ERRORS[status]);
} else {
var serverName = $("#"+serverID).parent().parent().find("a.name").text();
$("#error-success p").html("<b>" + serverName + "</b>" + ": " + ERRORS[status]);
}
} else {
......@@ -110,14 +120,14 @@
var CREATE_VM_SUCCESS_MSG = SUCCESS["CREATE_VM_SUCCESS_ONE"] + '<br />'
+ SUCCESS["CREATE_VM_SUCCESS_TWO"] + '<br /><br />' + '<b>' + password + '</b>'
+ '<br /><br />' + SUCCESS["CREATE_VM_SUCCESS_THREE"] ;
$("#error-success p").html(CREATE_VM_SUCCESS_MSG);
$("#error-success div").html("<p>" + CREATE_VM_SUCCESS_MSG + "</p>");
} else {
$("#error-success h3").text(SUCCESS['HEADER']);
$("#error-success p").text(SUCCESS[status]);
$("#error-success div").text("<p>" + SUCCESS[status] + "</p>");
}
} else {
$("#error-success h3").text(SUCCESS['HEADER']);
$("#error-success p").text(SUCCESS['DEFAULT']);
$("#error-success div").html("<p>" + SUCCESS['DEFAULT'] + "</p>");
}
......
......@@ -260,10 +260,10 @@ function display_success(serverID) {
}
// indicate that the requested action was not completed
function display_failure(serverID, status, action) {
function display_failure(status, serverID, action, responseText) {
osIcon = $('#'+serverID).parent().parent().find('.list-logo');
osIcon.attr('src',osIcon.attr('os'));
ajax_error(status, serverID);
ajax_error(status, serverID, action, responseText);
}
var vmTable = $("div.list table.list-machines").dataTable({
......
......@@ -151,7 +151,7 @@
<div class="modal" id="error-success">
<h3>{% trans "Error!/Success!" %}</h3>
<p>{% trans "More details about the result"%}</p>
<div><p>{% trans "More details about the result"%}</p></div>
</div>
<!-- confirmation before executing an action -->
......
......@@ -37,6 +37,7 @@
</div>
<div class="action_error" align="center">
{% trans "<span class='orange'>Error</span> on" %} <span class="action">error action</span>
<span class="code"></span>
<span class="message"></span>
<button class="details">Details</button>
</div>
......@@ -150,7 +151,7 @@ $("div.confirm_single .no").live('click', function(){
$("div.action_error .details").live('click', function(){
// remove the action from the pending list
ajax_error($(this).parent().children('.message').text());
ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
$(this).parent().hide();
});
......@@ -258,10 +259,11 @@ function display_success(serverID) {
}
// indicate that the requested action was not completed
function display_failure(serverID, status, action) {
function display_failure(status, serverID, action, responseText) {
$('#'+serverID+ ' .spinner').hide();
$('#'+serverID+ ' .action_error .action').text(action);
$('#'+serverID+ ' .action_error .message').text(status);
$('#'+serverID+ ' .action_error .code').text(status);
$('#'+serverID+ ' .action_error .message').text(responseText);
$('#'+serverID+ ' .action_error').show();
}
......
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