Better error management
This commit is contained in:
parent
df2109206a
commit
0adeb3a349
@ -1 +1 @@
|
||||
CACHE MANIFEST
# v14
CACHE:
index.html
css/main-min.css
js/main-min.js
js/require.js
img/ajax-loader.gif
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
||||
CACHE MANIFEST
# v15
CACHE:
index.html
css/main-min.css
js/main-min.js
js/require.js
img/ajax-loader.gif
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
||||
|
7
css/main-min.css
vendored
7
css/main-min.css
vendored
@ -5565,13 +5565,16 @@ hr {
|
||||
height: 16px;
|
||||
background-position: -109px 0;
|
||||
}
|
||||
.icon-spinner {
|
||||
background-image: url("../img/ajax-loader.gif");
|
||||
.working-indicator {
|
||||
background-image: none;
|
||||
width: 43px;
|
||||
height: 11px;
|
||||
background-position: 0 0;
|
||||
margin: 14px 15px 0;
|
||||
}
|
||||
.working-indicator.show {
|
||||
background-image: url("../img/ajax-loader.gif");
|
||||
}
|
||||
.ui-layout-toggler-north .caret, .ui-layout-toggler-south .caret {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
@ -274,14 +274,18 @@ hr {
|
||||
background-position: -109px 0;
|
||||
}
|
||||
|
||||
.icon-spinner {
|
||||
background-image: url("../img/ajax-loader.gif");
|
||||
.working-indicator {
|
||||
background-image: none;
|
||||
width: 43px;
|
||||
height: 11px;
|
||||
background-position: 0 0;
|
||||
margin: 14px 15px 0;
|
||||
}
|
||||
|
||||
.working-indicator.show {
|
||||
background-image: url("../img/ajax-loader.gif");
|
||||
}
|
||||
|
||||
.ui-layout-toggler-north .caret, .ui-layout-toggler-south .caret {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
39
index.html
39
index.html
@ -19,7 +19,7 @@
|
||||
dep = "main";
|
||||
css = "css/main.css";
|
||||
}
|
||||
document.write('<link href="' + css + '" rel="stylesheet" media="screen">');
|
||||
document.write('<link href="' + css + '" rel="stylesheet" media="screen">');
|
||||
var require = { baseUrl : "js", deps : [ dep ] };
|
||||
</script>
|
||||
<script src="js/require.js"></script>
|
||||
@ -111,7 +111,7 @@
|
||||
</ul></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<li><i class="working-indicator icon-spinner hide"></i></li>
|
||||
<li><i class="working-indicator icon-none"></i></li>
|
||||
<li><a class="brand" id="file-title" href="#"
|
||||
title="Rename current document"> </a></li>
|
||||
<li class="navbar-form"><input id="file-title-input"
|
||||
@ -321,7 +321,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group modal-publish-blogger">
|
||||
<label class="control-label" for="input-publish-blogger-labels">Labels (comma separated)</label>
|
||||
<label class="control-label" for="input-publish-blogger-labels">Labels
|
||||
(comma separated)</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-publish-blogger-labels"
|
||||
placeholder="Label1, Label2">
|
||||
@ -344,23 +345,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group modal-publish-gdrive">
|
||||
<div class="controls muted">
|
||||
If no file ID is supplied, the file will be created
|
||||
into your Google Drive root folder. You can move the file afterwards within
|
||||
Google Drive.
|
||||
</div>
|
||||
<div class="controls muted">If no file ID is supplied, the
|
||||
file will be created into your Google Drive root folder. You can
|
||||
move the file afterwards within Google Drive.</div>
|
||||
</div>
|
||||
<div class="control-group modal-publish-gdrive">
|
||||
<label class="control-label" for="input-publish-gdrive-filename">Force file name (optional)</label>
|
||||
<label class="control-label" for="input-publish-gdrive-filename">Force
|
||||
file name (optional)</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-publish-gdrive-filename"
|
||||
placeholder="File name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group modal-publish-gdrive">
|
||||
<div class="controls muted">
|
||||
If no file name is supplied, the document title will be used.
|
||||
</div>
|
||||
<div class="controls muted">If no file name is supplied, the
|
||||
document title will be used.</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
@ -435,8 +434,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-settings-scroll-link">Scroll Link <a
|
||||
href="#" class="tooltip-scroll-link">(?)</a></label>
|
||||
<label class="control-label" for="input-settings-scroll-link">Scroll
|
||||
Link <a href="#" class="tooltip-scroll-link">(?)</a>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" id="input-settings-scroll-link" />
|
||||
</div>
|
||||
@ -540,7 +540,9 @@
|
||||
<a target="_blank" href="http://twitter.github.io/bootstrap/">Bootstrap</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank" href="https://github.com/rafaelp/css_browser_selector/">CSS Browser Selector</a>
|
||||
<a target="_blank"
|
||||
href="https://github.com/rafaelp/css_browser_selector/">CSS
|
||||
Browser Selector</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank" href="https://github.com/dropbox/dropbox-js">Dropbox-js</a>
|
||||
@ -587,13 +589,14 @@
|
||||
href="http://www.apache.org/licenses/LICENSE-2.0">Apache License</a></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||
<a href="#" class="btn action-welcome-file" data-dismiss="modal">Welcome
|
||||
document</a> <a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-non-unique" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<h3>Stopped...</h3>
|
||||
<h3>Whoops...</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>StackEdit has stopped because another instance was running in
|
||||
@ -607,7 +610,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<textarea id="md-section-helper"></textarea>
|
||||
<textarea id="md-section-helper"></textarea>
|
||||
<div id="dropboxjs" data-app-key="x0k2l8puemfvg0o"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -470,6 +470,7 @@
|
||||
Markdown.Extra.prototype.all = function(text) {
|
||||
text = this.tables(text);
|
||||
text = this.fencedCodeBlocks(text);
|
||||
text = this.definitionLists(text);
|
||||
return text;
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,10 @@ define([ "core", "underscore" ], function(core) {
|
||||
if (task.finished === true) {
|
||||
return;
|
||||
}
|
||||
error = error || "Unknown error";
|
||||
error = error || new Error("Unknown error");
|
||||
if(error.message) {
|
||||
core.showError(error.message);
|
||||
}
|
||||
runSafe(task, task.errorCallbacks, error);
|
||||
// Exit the current call stack
|
||||
throw error;
|
||||
@ -87,13 +90,14 @@ define([ "core", "underscore" ], function(core) {
|
||||
/**
|
||||
* retry() can be called in an onRun callback to restart the task
|
||||
*/
|
||||
task.retry = function() {
|
||||
task.retry = function(error, maxRetryCounter) {
|
||||
if (task.finished === true) {
|
||||
return;
|
||||
}
|
||||
maxRetryCounter = maxRetryCounter || 5;
|
||||
task.queue = undefined;
|
||||
if (task.retryCounter === 5) {
|
||||
task.error(new Error("Maximum retry number reached"));
|
||||
if (task.retryCounter >= maxRetryCounter) {
|
||||
task.error(error);
|
||||
return;
|
||||
}
|
||||
// Implement an exponential backoff
|
||||
@ -112,9 +116,7 @@ define([ "core", "underscore" ], function(core) {
|
||||
if (currentTaskRunning === true) {
|
||||
// If the current task takes too long
|
||||
if (currentTaskStartTime + currentTask.timeout < core.currentTime) {
|
||||
var errorMsg = "A timeout occurred.";
|
||||
core.showError(errorMsg);
|
||||
currentTask.error(new Error(errorMsg));
|
||||
currentTask.error(new Error("A timeout occurred."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ var PROVIDER_BLOGGER = "blogger";
|
||||
var PROVIDER_DROPBOX = "dropbox";
|
||||
var PROVIDER_GDRIVE = "gdrive";
|
||||
var PROVIDER_GITHUB = "github";
|
||||
var WELCOME_DOCUMENT_TITLE = "Welcome document";
|
||||
|
||||
// Use by Google's client.js
|
||||
var delayedFunction = undefined;
|
||||
|
25
js/core.js
25
js/core.js
@ -127,10 +127,10 @@ define(
|
||||
// Used by asyncRunner
|
||||
core.showWorkingIndicator = function(show) {
|
||||
if (show === false) {
|
||||
$(".working-indicator").addClass("hide");
|
||||
$(".working-indicator").removeClass("show");
|
||||
$("body").removeClass("working");
|
||||
} else {
|
||||
$(".working-indicator").removeClass("hide");
|
||||
$(".working-indicator").addClass("show");
|
||||
$("body").addClass("working");
|
||||
}
|
||||
};
|
||||
@ -293,7 +293,7 @@ define(
|
||||
var offset = 0, mdSectionOffset = 0;
|
||||
function addMdSection(sectionText) {
|
||||
var sectionHeight = padding;
|
||||
if(sectionText) {
|
||||
if(sectionText !== undefined) {
|
||||
textareaElt.val(sectionText);
|
||||
sectionHeight += textareaElt.prop('scrollHeight');
|
||||
}
|
||||
@ -313,7 +313,11 @@ define(
|
||||
if(title) {
|
||||
// We just found a title which means end of the previous section
|
||||
// Exclude last \n of the section
|
||||
addMdSection(text.substring(offset, matchOffset-1));
|
||||
var sectionText = undefined;
|
||||
if(matchOffset > offset) {
|
||||
sectionText = text.substring(offset, matchOffset-1);
|
||||
}
|
||||
addMdSection(sectionText);
|
||||
offset = matchOffset;
|
||||
}
|
||||
return "";
|
||||
@ -358,8 +362,9 @@ define(
|
||||
lastEditorScrollTop = -9;
|
||||
lastPreviewScrollTop = -9;
|
||||
scrollLink();
|
||||
}, 800);
|
||||
}, 500);
|
||||
|
||||
// -9 is less than -5
|
||||
var lastEditorScrollTop = -9;
|
||||
var lastPreviewScrollTop = -9;
|
||||
var scrollLink = _.debounce(function() {
|
||||
@ -379,11 +384,12 @@ define(
|
||||
});
|
||||
if(srcSection === undefined) {
|
||||
// Something wrong in the algorithm...
|
||||
return 0;
|
||||
return -9;
|
||||
}
|
||||
var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height;
|
||||
var destSection = destSectionList[sectionIndex];
|
||||
var destScrollTop = destSection.startOffset + destSection.height * posInSection;
|
||||
destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]);
|
||||
destElt.animate({scrollTop: destScrollTop}, 800, function() {
|
||||
lastEditorScrollTop = editorElt.scrollTop();
|
||||
lastPreviewScrollTop = previewElt.scrollTop();
|
||||
@ -396,7 +402,7 @@ define(
|
||||
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
|
||||
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList);
|
||||
}
|
||||
}, 1200);
|
||||
}, 1000);
|
||||
|
||||
// Create the layout
|
||||
var layout = undefined;
|
||||
@ -486,6 +492,11 @@ define(
|
||||
// Modify scroll position of the preview not the editor
|
||||
lastEditorScrollTop = -9;
|
||||
buildSections();
|
||||
// Preview may change if images are loading
|
||||
$("#wmd-preview img").load(function() {
|
||||
lastEditorScrollTop = -9;
|
||||
buildSections();
|
||||
});
|
||||
});
|
||||
}
|
||||
// Custom insert link dialog
|
||||
|
@ -10,8 +10,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
task.onRun(function() {
|
||||
if(core.isOffline === true) {
|
||||
client = undefined;
|
||||
core.showMessage("Operation not available in offline mode.");
|
||||
task.error();
|
||||
task.error(new Error("Operation not available in offline mode."));
|
||||
return;
|
||||
}
|
||||
if (client !== undefined) {
|
||||
@ -31,9 +30,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
rememberUser: true
|
||||
}));
|
||||
task.chain();
|
||||
}).fail(function() {
|
||||
core.setOffline();
|
||||
task.error(new Error("Network timeout|stopPublish"));
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
status: jqXHR.status,
|
||||
responseText: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -67,9 +69,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
return;
|
||||
}
|
||||
// Error
|
||||
var errorMsg = "Access to Dropbox account is not authorized.";
|
||||
core.showError(errorMsg);
|
||||
task.error(new Error(errorMsg));
|
||||
task.error(new Error("Access to Dropbox account is not authorized."));
|
||||
});
|
||||
}
|
||||
task.chain(localAuthenticate);
|
||||
@ -93,7 +93,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
if(error.status === Dropbox.ApiError.INVALID_PARAM) {
|
||||
error = 'Could not upload document into path "' + path + '".';
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
task.onSuccess(function() {
|
||||
@ -116,7 +116,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
function retrievePageOfChanges() {
|
||||
client.pullChanges(newChangeId, function(error, pullChanges) {
|
||||
if (error) {
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
return;
|
||||
}
|
||||
// Retrieve success
|
||||
@ -161,7 +161,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
task.chain(recursiveDownloadMetadata);
|
||||
return;
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
}
|
||||
task.chain(recursiveDownloadMetadata);
|
||||
@ -208,7 +208,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
recursiveDownloadContent();
|
||||
return;
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
}
|
||||
task.chain(recursiveDownloadContent);
|
||||
@ -222,40 +222,43 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
asyncRunner.addTask(task);
|
||||
};
|
||||
|
||||
function handleError(error, task, callback) {
|
||||
function handleError(error, task) {
|
||||
var errorMsg = true;
|
||||
if (error) {
|
||||
console.error(error);
|
||||
// Try to analyze the error
|
||||
if (typeof error === "string") {
|
||||
errorMsg = error;
|
||||
} else if (error.status === Dropbox.ApiError.INVALID_TOKEN
|
||||
|| error.status === Dropbox.ApiError.OAUTH_ERROR) {
|
||||
authenticated = false;
|
||||
task.retry();
|
||||
return;
|
||||
} else if(error.status === Dropbox.ApiError.INVALID_PARAM && error.responseText
|
||||
.indexOf("oauth_nonce") !== -1) {
|
||||
// A bug I guess...
|
||||
_.each(_.keys(localStorage), function(key) {
|
||||
// We have to remove the Oauth cache from the localStorage
|
||||
if(key.indexOf("dropbox-auth") === 0) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
authenticated = false;
|
||||
task.retry();
|
||||
return;
|
||||
} else if (error.status === Dropbox.ApiError.NETWORK_ERROR) {
|
||||
client = undefined;
|
||||
authenticated = false;
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
} else {
|
||||
errorMsg = "Dropbox error ("
|
||||
+ error.status + ").";
|
||||
}
|
||||
core.showError(errorMsg);
|
||||
else {
|
||||
errorMsg = "Dropbox error ("
|
||||
+ error.status + ": " + error.responseText + ").";
|
||||
|
||||
if (error.status === Dropbox.ApiError.INVALID_TOKEN
|
||||
|| error.status === Dropbox.ApiError.OAUTH_ERROR) {
|
||||
authenticated = false;
|
||||
errorMsg = "Access to Dropbox account is not authorized.";
|
||||
task.retry(new Error(errorMsg), 1);
|
||||
return;
|
||||
} else if(error.status === Dropbox.ApiError.INVALID_PARAM && error.responseText
|
||||
.indexOf("oauth_nonce") !== -1) {
|
||||
// A bug I guess...
|
||||
_.each(_.keys(localStorage), function(key) {
|
||||
// We have to remove the Oauth cache from the localStorage
|
||||
if(key.indexOf("dropbox-auth") === 0) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
authenticated = false;
|
||||
task.retry(new Error(errorMsg), 1);
|
||||
return;
|
||||
} else if (error.status === Dropbox.ApiError.NETWORK_ERROR || error.status < 0) {
|
||||
client = undefined;
|
||||
authenticated = false;
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
}
|
||||
}
|
||||
}
|
||||
task.error(new Error(errorMsg));
|
||||
}
|
||||
@ -273,9 +276,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
}).done(function() {
|
||||
pickerLoaded = true;
|
||||
task.chain();
|
||||
}).fail(function() {
|
||||
core.setOffline();
|
||||
task.error();
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
status: jqXHR.status,
|
||||
responseText: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
define(["jquery", "core", "synchronizer", "publisher", "underscore"],
|
||||
function($, core, synchronizer, publisher) {
|
||||
define(["jquery", "core", "synchronizer", "publisher", "text!../WELCOME.md", "underscore"],
|
||||
function($, core, synchronizer, publisher, welcomeContent) {
|
||||
|
||||
var fileManager = {};
|
||||
|
||||
@ -28,7 +28,7 @@ define(["jquery", "core", "synchronizer", "publisher", "underscore"],
|
||||
fileManager.selectFile = function(fileIndex) {
|
||||
// If no file create one
|
||||
if (localStorage["file.list"].length === 1) {
|
||||
fileIndex = this.createFile();
|
||||
fileIndex = fileManager.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
||||
}
|
||||
|
||||
if(fileIndex !== undefined) {
|
||||
@ -272,6 +272,10 @@ define(["jquery", "core", "synchronizer", "publisher", "underscore"],
|
||||
var title = localStorage[fileManager.getCurrentFileIndex() + ".title"];
|
||||
core.saveFile(content, title + ".txt");
|
||||
});
|
||||
$(".action-welcome-file").click(function() {
|
||||
var fileIndex = fileManager.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
||||
fileManager.selectFile(fileIndex);
|
||||
});
|
||||
});
|
||||
|
||||
core.setFileManager(fileManager);
|
||||
|
@ -10,8 +10,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
task.onRun(function() {
|
||||
if(core.isOffline === true) {
|
||||
connected = false;
|
||||
core.showMessage("Operation not available in offline mode.");
|
||||
task.error();
|
||||
task.error(new Error("Operation not available in offline mode."));
|
||||
return;
|
||||
}
|
||||
if (connected === true) {
|
||||
@ -24,9 +23,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
}).done(function() {
|
||||
connected = true;
|
||||
task.chain();
|
||||
}).fail(function() {
|
||||
core.setOffline();
|
||||
task.error(new Error("Network timeout|stopPublish"));
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
error: jqXHR.status,
|
||||
message: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -50,6 +52,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
return;
|
||||
}
|
||||
core.showMessage("Please make sure the Github authorization popup is not blocked by your browser.");
|
||||
var errorMsg = "Failed to retrieve a token from GitHub.";
|
||||
// We add time for user to enter his credentials
|
||||
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
||||
var code = undefined;
|
||||
@ -66,7 +69,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
intervalId = undefined;
|
||||
code = localStorage["githubCode"];
|
||||
if(code === undefined) {
|
||||
task.error();
|
||||
task.error(new Error(errorMsg));
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem("githubCode");
|
||||
@ -86,7 +89,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
task.chain();
|
||||
}
|
||||
else {
|
||||
task.error();
|
||||
task.error(new Error(errorMsg));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -113,7 +116,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
var user = github.getUser();
|
||||
user.show(undefined, function(err, result) {
|
||||
if(err) {
|
||||
task.error(err);
|
||||
handleError(err, task);
|
||||
return;
|
||||
}
|
||||
userLogin = result.login;
|
||||
@ -124,7 +127,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
var repo = github.getRepo(userLogin, reponame);
|
||||
repo.write(branch, path, content, commitMsg, function(err) {
|
||||
if(err) {
|
||||
task.error(err);
|
||||
handleError(err, task);
|
||||
return;
|
||||
}
|
||||
task.chain();
|
||||
@ -135,27 +138,37 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
task.onSuccess(function() {
|
||||
callback();
|
||||
});
|
||||
task.onError(function(err) {
|
||||
var errorMsg = "Could not publish on GitHub.";
|
||||
if(err !== undefined) {
|
||||
console.error(err);
|
||||
if(err.error === 401 || err.error === 403) {
|
||||
github = undefined;
|
||||
// Token must be renewed
|
||||
localStorage.removeItem("githubToken");
|
||||
errorMsg = "Access to GitHub is not authorized.";
|
||||
}
|
||||
else if(err.error === 0) {
|
||||
connected = false;
|
||||
github = undefined;
|
||||
core.setOffline();
|
||||
}
|
||||
}
|
||||
core.showError(errorMsg);
|
||||
callback(errorMsg);
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
var errorMsg = undefined;
|
||||
if (error) {
|
||||
console.error(error);
|
||||
// Try to analyze the error
|
||||
if (typeof error === "string") {
|
||||
errorMsg = error;
|
||||
}
|
||||
else {
|
||||
errorMsg = "Could not publish on GitHub.";
|
||||
if (error.error === 401 || error.error === 403) {
|
||||
github = undefined;
|
||||
errorMsg = "Access to GitHub account is not authorized.";
|
||||
task.retry(new Error(errorMsg), 1);
|
||||
return;
|
||||
} else if (error.error <= 0) {
|
||||
connected = false;
|
||||
github = undefined;
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
}
|
||||
}
|
||||
}
|
||||
task.error(new Error(errorMsg));
|
||||
}
|
||||
|
||||
return githubHelper;
|
||||
});
|
||||
|
@ -10,8 +10,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
task.onRun(function() {
|
||||
if(core.isOffline === true) {
|
||||
connected = false;
|
||||
core.showMessage("Operation not available in offline mode.");
|
||||
task.error();
|
||||
task.error(new Error("Operation not available in offline mode."));
|
||||
return;
|
||||
}
|
||||
if (connected === true) {
|
||||
@ -25,9 +24,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
$.ajax({
|
||||
url : "https://apis.google.com/js/client.js?onload=runDelayedFunction",
|
||||
dataType : "script", timeout : AJAX_TIMEOUT
|
||||
}).fail(function() {
|
||||
core.setOffline();
|
||||
task.error(new Error("Network timeout|stopPublish"));
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
code: jqXHR.status,
|
||||
message: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -58,9 +60,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
return;
|
||||
}
|
||||
// Error
|
||||
var errorMsg = "Access to Google account is not authorized.";
|
||||
core.showError(errorMsg);
|
||||
task.error(new Error(errorMsg));
|
||||
task.error(new Error("Access to Google account is not authorized."));
|
||||
return;
|
||||
}
|
||||
// Success
|
||||
@ -137,7 +137,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
error = 'Conflict on file ID "' + fileId + '". Please restart the synchronization.';
|
||||
}
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
task.onSuccess(function() {
|
||||
@ -172,7 +172,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
request.execute(function(response) {
|
||||
if (!response || !response.largestChangeId) {
|
||||
// Handle error
|
||||
handleError(response.error, task, callback);
|
||||
handleError(response.error, task);
|
||||
return;
|
||||
}
|
||||
// Retrieve success
|
||||
@ -234,7 +234,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
if(error.code === 404) {
|
||||
error = 'File ID "' + id + '" not found on Google Drive.';
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
}
|
||||
task.chain(recursiveDownloadMetadata);
|
||||
@ -295,7 +295,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
message: jqXHR.statusText
|
||||
};
|
||||
// Handle error
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
}
|
||||
task.chain(recursiveDownloadContent);
|
||||
@ -309,7 +309,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
asyncRunner.addTask(task);
|
||||
};
|
||||
|
||||
function handleError(error, task, callback) {
|
||||
function handleError(error, task) {
|
||||
var errorMsg = undefined;
|
||||
if (error) {
|
||||
console.error(error);
|
||||
@ -317,24 +317,25 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
if (typeof error === "string") {
|
||||
errorMsg = error;
|
||||
}
|
||||
else if (error.code >= 500 && error.code < 600) {
|
||||
// Retry as described in Google's best practices
|
||||
task.retry();
|
||||
return;
|
||||
} else if (error.code === 401 || error.code === 403) {
|
||||
authenticated = false;
|
||||
task.retry();
|
||||
return;
|
||||
} else if (error.code <= 0) {
|
||||
connected = false;
|
||||
authenticated = false;
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
} else {
|
||||
else {
|
||||
errorMsg = "Google error (" + error.code + ": "
|
||||
+ error.message + ").";
|
||||
if (error.code >= 500 && error.code < 600) {
|
||||
// Retry as described in Google's best practices
|
||||
task.retry(new Error(errorMsg));
|
||||
return;
|
||||
} else if (error.code === 401 || error.code === 403) {
|
||||
authenticated = false;
|
||||
errorMsg = "Access to Google account is not authorized.";
|
||||
task.retry(new Error(errorMsg), 1);
|
||||
return;
|
||||
} else if (error.code <= 0) {
|
||||
connected = false;
|
||||
authenticated = false;
|
||||
core.setOffline();
|
||||
errorMsg = "|stopPublish";
|
||||
}
|
||||
}
|
||||
core.showError(errorMsg);
|
||||
}
|
||||
task.error(new Error(errorMsg));
|
||||
}
|
||||
@ -353,9 +354,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
}).done(function() {
|
||||
google.load('picker', '1', {callback: task.chain});
|
||||
pickerLoaded = true;
|
||||
}).fail(function() {
|
||||
core.setOffline();
|
||||
task.error(new Error("Network timeout"));
|
||||
}).fail(function(jqXHR) {
|
||||
var error = {
|
||||
code: jqXHR.status,
|
||||
message: jqXHR.statusText
|
||||
};
|
||||
handleError(error, task);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -364,6 +368,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
callback = callback || core.doNothing;
|
||||
var ids = [];
|
||||
var picker = undefined;
|
||||
function hidePicker() {
|
||||
if(picker !== undefined) {
|
||||
picker.setVisible(false);
|
||||
$(".modal-backdrop, .picker").remove();
|
||||
}
|
||||
}
|
||||
var task = asyncRunner.createTask();
|
||||
connect(task);
|
||||
loadPicker(task);
|
||||
@ -388,14 +398,13 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
ids.push(data.docs[i].id);
|
||||
}
|
||||
}
|
||||
$(".modal-backdrop, .picker").remove();
|
||||
hidePicker();
|
||||
task.chain();
|
||||
}
|
||||
});
|
||||
picker = pickerBuilder.build();
|
||||
$("body").append($("<div>").addClass("modal-backdrop").click(function() {
|
||||
picker.setVisible(false);
|
||||
$(".modal-backdrop, .picker").remove();
|
||||
hidePicker();
|
||||
task.chain();
|
||||
}));
|
||||
picker.setVisible(true);
|
||||
@ -404,11 +413,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
callback(undefined, ids);
|
||||
});
|
||||
task.onError(function(error) {
|
||||
if(picker !== undefined) {
|
||||
picker.setVisible(false);
|
||||
$(".modal-backdrop, .picker").remove();
|
||||
task.chain();
|
||||
}
|
||||
hidePicker();
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
@ -459,7 +464,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
if(error.code === 404 && postId !== undefined) {
|
||||
error = 'Post ' + postId + ' not found on Blogger.|removePublish';
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
}
|
||||
function getBlogId() {
|
||||
@ -485,7 +490,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
||||
if(error.code === 404) {
|
||||
error = 'Blog "' + blogUrl + '" not found on Blogger.|removePublish';
|
||||
}
|
||||
handleError(error, task, callback);
|
||||
handleError(error, task);
|
||||
});
|
||||
}
|
||||
task.chain(getBlogId);
|
||||
|
8
js/main-min.js
vendored
8
js/main-min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user