mirror of
https://github.com/laurent22/joplin.git
synced 2025-03-29 21:21:15 +02:00
All: Dropbox: Handle various error conditions
This commit is contained in:
parent
3c2281dbf9
commit
6e994fd8b9
@ -92,7 +92,7 @@ class Command extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = await api.execAuthToken(authCode);
|
const response = await api.execAuthToken(authCode);
|
||||||
Setting.setValue('sync.' + this.syncTargetId_ + '.auth', JSON.stringify(response));
|
Setting.setValue('sync.' + this.syncTargetId_ + '.auth', response.access_token);
|
||||||
api.setAuthToken(response.access_token);
|
api.setAuthToken(response.access_token);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ class DropboxLoginScreenComponent extends React.Component {
|
|||||||
const api = await this.dropboxApi();
|
const api = await this.dropboxApi();
|
||||||
try {
|
try {
|
||||||
const response = await api.execAuthToken(this.state.authCode);
|
const response = await api.execAuthToken(this.state.authCode);
|
||||||
Setting.setValue('sync.' + this.syncTargetId() + '.auth', JSON.stringify(response));
|
Setting.setValue('sync.' + this.syncTargetId() + '.auth', response.access_token);
|
||||||
api.setAuthToken(response.access_token);
|
api.setAuthToken(response.access_token);
|
||||||
bridge().showInfoMessageBox(_('The application has been authorised!'));
|
bridge().showInfoMessageBox(_('The application has been authorised!'));
|
||||||
this.props.dispatch({ type: 'NAV_BACK' });
|
this.props.dispatch({ type: 'NAV_BACK' });
|
||||||
|
@ -370,7 +370,7 @@ class NoteTextComponent extends React.Component {
|
|||||||
webviewReady: true,
|
webviewReady: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Setting.value('env') === 'dev') this.webview_.openDevTools();
|
// if (Setting.value('env') === 'dev') this.webview_.openDevTools();
|
||||||
}
|
}
|
||||||
|
|
||||||
webview_ref(element) {
|
webview_ref(element) {
|
||||||
|
@ -3,6 +3,7 @@ const { shim } = require('lib/shim.js');
|
|||||||
const JoplinError = require('lib/JoplinError');
|
const JoplinError = require('lib/JoplinError');
|
||||||
const URL = require('url-parse');
|
const URL = require('url-parse');
|
||||||
const { time } = require('lib/time-utils');
|
const { time } = require('lib/time-utils');
|
||||||
|
const EventDispatcher = require('lib/EventDispatcher');
|
||||||
|
|
||||||
class DropboxApi {
|
class DropboxApi {
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ class DropboxApi {
|
|||||||
this.logger_ = new Logger();
|
this.logger_ = new Logger();
|
||||||
this.options_ = options;
|
this.options_ = options;
|
||||||
this.authToken_ = null;
|
this.authToken_ = null;
|
||||||
|
this.dispatcher_ = new EventDispatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
clientId() {
|
clientId() {
|
||||||
@ -32,8 +34,13 @@ class DropboxApi {
|
|||||||
return this.authToken_; // Without the "Bearer " prefix
|
return this.authToken_; // Without the "Bearer " prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on(eventName, callback) {
|
||||||
|
return this.dispatcher_.on(eventName, callback);
|
||||||
|
}
|
||||||
|
|
||||||
setAuthToken(v) {
|
setAuthToken(v) {
|
||||||
this.authToken_ = v;
|
this.authToken_ = v;
|
||||||
|
this.dispatcher_.dispatch('authRefreshed', this.authToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
loginUrl() {
|
loginUrl() {
|
||||||
@ -90,6 +97,12 @@ class DropboxApi {
|
|||||||
return JSON.parse(responseText);
|
return JSON.parse(responseText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isTokenError(status, responseText) {
|
||||||
|
if (status === 401) return true;
|
||||||
|
if (responseText.indexOf('OAuth 2 access token is malformed') >= 0) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async exec(method, path = '', body = null, headers = null, options = null) {
|
async exec(method, path = '', body = null, headers = null, options = null) {
|
||||||
if (headers === null) headers = {};
|
if (headers === null) headers = {};
|
||||||
if (options === null) options = {};
|
if (options === null) options = {};
|
||||||
@ -124,8 +137,7 @@ class DropboxApi {
|
|||||||
|
|
||||||
// console.info(this.requestToCurl_(url, fetchOptions));
|
// console.info(this.requestToCurl_(url, fetchOptions));
|
||||||
|
|
||||||
const now = Date.now();
|
// console.info(method + ' ' + url);
|
||||||
// console.info(now + ': ' + method + ' ' + url);
|
|
||||||
|
|
||||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||||
response = await shim.uploadBlob(url, fetchOptions);
|
response = await shim.uploadBlob(url, fetchOptions);
|
||||||
@ -137,7 +149,7 @@ class DropboxApi {
|
|||||||
|
|
||||||
const responseText = await response.text();
|
const responseText = await response.text();
|
||||||
|
|
||||||
// console.info(now + ': Response: ' + responseText);
|
// console.info('Response: ' + responseText);
|
||||||
|
|
||||||
let responseJson_ = null;
|
let responseJson_ = null;
|
||||||
const loadResponseJson = () => {
|
const loadResponseJson = () => {
|
||||||
@ -162,10 +174,17 @@ class DropboxApi {
|
|||||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||||
const shortResponseText = (responseText + '').substr(0, 1024);
|
const shortResponseText = (responseText + '').substr(0, 1024);
|
||||||
return new JoplinError(method + ' ' + path + ': ' + message + ' (' + response.status + '): ' + shortResponseText, code);
|
const error = new JoplinError(method + ' ' + path + ': ' + message + ' (' + response.status + '): ' + shortResponseText, code);
|
||||||
|
error.httpStatus = response.status;
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
const json = loadResponseJson();
|
||||||
|
if (this.isTokenError(response.status, responseText)) {
|
||||||
|
this.setAuthToken(null);
|
||||||
|
}
|
||||||
|
|
||||||
// When using fetchBlob we only get a string (not xml or json) back
|
// When using fetchBlob we only get a string (not xml or json) back
|
||||||
if (options.target === 'file') throw newError('fetchBlob error');
|
if (options.target === 'file') throw newError('fetchBlob error');
|
||||||
|
|
||||||
|
@ -32,4 +32,4 @@ class EventDispatcher {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { EventDispatcher };
|
module.exports = EventDispatcher;
|
@ -40,10 +40,6 @@ class SyncTargetDropbox extends BaseSyncTarget {
|
|||||||
return fileApi.driver().api();
|
return fileApi.driver().api();
|
||||||
}
|
}
|
||||||
|
|
||||||
syncTargetId() {
|
|
||||||
return SyncTargetDropbox.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
async initFileApi() {
|
async initFileApi() {
|
||||||
const params = parameters().dropbox;
|
const params = parameters().dropbox;
|
||||||
|
|
||||||
@ -52,15 +48,17 @@ class SyncTargetDropbox extends BaseSyncTarget {
|
|||||||
secret: params.secret,
|
secret: params.secret,
|
||||||
});
|
});
|
||||||
|
|
||||||
const authJson = Setting.value('sync.' + SyncTargetDropbox.id() + '.auth');
|
api.on('authRefreshed', (auth) => {
|
||||||
if (authJson) {
|
this.logger().info('Saving updated OneDrive auth.');
|
||||||
const auth = JSON.parse(authJson);
|
Setting.setValue('sync.' + SyncTargetDropbox.id() + '.auth', auth ? auth : null);
|
||||||
api.setAuthToken(auth.access_token);
|
});
|
||||||
}
|
|
||||||
|
const authToken = Setting.value('sync.' + SyncTargetDropbox.id() + '.auth');
|
||||||
|
api.setAuthToken(authToken);
|
||||||
|
|
||||||
const appDir = '';
|
const appDir = '';
|
||||||
const fileApi = new FileApi(appDir, new FileApiDriverDropbox(api));
|
const fileApi = new FileApi(appDir, new FileApiDriverDropbox(api));
|
||||||
fileApi.setSyncTargetId(this.syncTargetId());
|
fileApi.setSyncTargetId(SyncTargetDropbox.id());
|
||||||
fileApi.setLogger(this.logger());
|
fileApi.setLogger(this.logger());
|
||||||
return fileApi;
|
return fileApi;
|
||||||
}
|
}
|
||||||
|
@ -66,22 +66,32 @@ class FileApiDriverDropbox {
|
|||||||
const context = options ? options.context : null;
|
const context = options ? options.context : null;
|
||||||
let cursor = context ? context.cursor : null;
|
let cursor = context ? context.cursor : null;
|
||||||
|
|
||||||
const urlPath = cursor ? 'files/list_folder/continue' : 'files/list_folder';
|
while (true) {
|
||||||
const body = cursor ? { cursor: cursor } : { path: this.makePath_(path), include_deleted: true };
|
const urlPath = cursor ? 'files/list_folder/continue' : 'files/list_folder';
|
||||||
const response = await this.api().exec('POST', urlPath, body);
|
const body = cursor ? { cursor: cursor } : { path: this.makePath_(path), include_deleted: true };
|
||||||
|
|
||||||
const output = {
|
try {
|
||||||
items: this.metadataToStats_(response.entries),
|
const response = await this.api().exec('POST', urlPath, body);
|
||||||
hasMore: response.has_more,
|
|
||||||
context: { cursor: response.cursor },
|
const output = {
|
||||||
|
items: this.metadataToStats_(response.entries),
|
||||||
|
hasMore: response.has_more,
|
||||||
|
context: { cursor: response.cursor },
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
} catch (error) {
|
||||||
|
// If there's an error related to an invalid cursor, clear the cursor and retry.
|
||||||
|
if (cursor) {
|
||||||
|
if (error.httpStatus === 400 || error.code.indexOf('reset') >= 0) {
|
||||||
|
// console.info('Clearing cursor and retrying', error);
|
||||||
|
cursor = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: handle error - reset cursor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async list(path, options) {
|
async list(path, options) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user