mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
All: Handle case where resource blob is missing during sync
This commit is contained in:
parent
e355f4e49b
commit
86eee376bb
@ -683,12 +683,12 @@ describe('Synchronizer', function() {
|
||||
|
||||
await switchClient(2);
|
||||
|
||||
synchronizer().debugFlags_ = ['cancelDeltaLoop2'];
|
||||
synchronizer().testingHooks_ = ['cancelDeltaLoop2'];
|
||||
let context = await synchronizer().start();
|
||||
let notes = await Note.all();
|
||||
expect(notes.length).toBe(0);
|
||||
|
||||
synchronizer().debugFlags_ = [];
|
||||
synchronizer().testingHooks_ = [];
|
||||
await synchronizer().start({ context: context });
|
||||
notes = await Note.all();
|
||||
expect(notes.length).toBe(1);
|
||||
@ -702,9 +702,9 @@ describe('Synchronizer', function() {
|
||||
let disabledItems = await BaseItem.syncDisabledItems(syncTargetId());
|
||||
expect(disabledItems.length).toBe(0);
|
||||
await Note.save({ id: noteId, title: "un mod", });
|
||||
synchronizer().debugFlags_ = ['rejectedByTarget'];
|
||||
synchronizer().testingHooks_ = ['rejectedByTarget'];
|
||||
await synchronizer().start();
|
||||
synchronizer().debugFlags_ = [];
|
||||
synchronizer().testingHooks_ = [];
|
||||
await synchronizer().start(); // Another sync to check that this item is now excluded from sync
|
||||
|
||||
await switchClient(2);
|
||||
|
@ -121,7 +121,7 @@ class EncryptionConfigScreenComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const decryptedItemsInfo = this.props.encryptionEnabled ? <p style={theme.textStyle}>{shared.decryptedStatText(this)}</p> : null;
|
||||
const decryptedItemsInfo = <p style={theme.textStyle}>{shared.decryptedStatText(this)}</p>;
|
||||
const toggleButton = <button onClick={() => { onToggleButtonClick() }}>{this.props.encryptionEnabled ? _('Disable encryption') : _('Enable encryption')}</button>
|
||||
|
||||
let masterKeySection = null;
|
||||
|
@ -3,6 +3,15 @@
|
||||
// Make it possible to require("/lib/...") without specifying full path
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
// Disable React message in console "Download the React DevTools for a better development experience"
|
||||
// https://stackoverflow.com/questions/42196819/disable-hide-download-the-react-devtools#42196820
|
||||
__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
|
||||
supportsFiber: true,
|
||||
inject: function() {},
|
||||
onCommitFiberRoot: function() {},
|
||||
onCommitFiberUnmount: function() {},
|
||||
};
|
||||
|
||||
const { app } = require('./app.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
|
@ -73,7 +73,7 @@ class MdToHtml {
|
||||
|
||||
renderImage_(attrs, options) {
|
||||
const loadResource = async (id) => {
|
||||
console.info('Loading resource: ' + id);
|
||||
// console.info('Loading resource: ' + id);
|
||||
|
||||
// Initially set to to an empty object to make
|
||||
// it clear that it is being loaded. Otherwise
|
||||
|
@ -1,5 +1,7 @@
|
||||
const { isHidden } = require('lib/path-utils.js');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const JoplinError = require('lib/JoplinError');
|
||||
|
||||
class FileApi {
|
||||
|
||||
@ -10,6 +12,10 @@ class FileApi {
|
||||
this.syncTargetId_ = null;
|
||||
}
|
||||
|
||||
fsDriver() {
|
||||
return shim.fsDriver();
|
||||
}
|
||||
|
||||
driver() {
|
||||
return this.driver_;
|
||||
}
|
||||
@ -83,8 +89,13 @@ class FileApi {
|
||||
return this.driver_.get(this.fullPath_(path), options);
|
||||
}
|
||||
|
||||
put(path, content, options = null) {
|
||||
this.logger().debug('put ' + this.fullPath_(path));
|
||||
async put(path, content, options = null) {
|
||||
this.logger().debug('put ' + this.fullPath_(path), options);
|
||||
|
||||
if (options && options.source === 'file') {
|
||||
if (!await this.fsDriver().exists(options.path)) throw new JoplinError('File not found: ' + options.path, 'fileNotFound');
|
||||
}
|
||||
|
||||
return this.driver_.put(this.fullPath_(path), content, options);
|
||||
}
|
||||
|
||||
|
@ -4,14 +4,20 @@ const { GeolocationNode } = require('lib/geolocation-node.js');
|
||||
const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { setLocale, defaultLocale, closestSupportedLocale } = require('lib/locale.js');
|
||||
const { FsDriverNode } = require('lib/fs-driver-node.js');
|
||||
|
||||
function shimInit() {
|
||||
shim.fs = fs;
|
||||
shim.fsDriver = () => { throw new Error('Not implemented') }
|
||||
shim.FileApiDriverLocal = FileApiDriverLocal;
|
||||
shim.Geolocation = GeolocationNode;
|
||||
shim.FormData = require('form-data');
|
||||
shim.sjclModule = require('lib/vendor/sjcl.js');
|
||||
|
||||
shim.fsDriver = () => {
|
||||
if (!shim.fsDriver_) shim.fsDriver_ = new FsDriverNode();
|
||||
return shim.fsDriver_;
|
||||
}
|
||||
|
||||
shim.randomBytes = async (count) => {
|
||||
const buffer = require('crypto').randomBytes(count);
|
||||
return Array.from(buffer);
|
||||
|
@ -3,6 +3,7 @@ const { GeolocationReact } = require('lib/geolocation-react.js');
|
||||
const { PoorManIntervals } = require('lib/poor-man-intervals.js');
|
||||
const RNFetchBlob = require('react-native-fetch-blob').default;
|
||||
const { generateSecureRandom } = require('react-native-securerandom');
|
||||
const FsDriverRN = require('lib/fs-driver-rn.js').FsDriverRN;
|
||||
|
||||
function shimInit() {
|
||||
shim.Geolocation = GeolocationReact;
|
||||
@ -10,6 +11,11 @@ function shimInit() {
|
||||
shim.clearInterval = PoorManIntervals.clearInterval;
|
||||
shim.sjclModule = require('lib/vendor/sjcl-rn.js');
|
||||
|
||||
shim.fsDriver = () => {
|
||||
if (!shim.fsDriver_) shim.fsDriver_ = new FsDriverRN();
|
||||
return shim.fsDriver_;
|
||||
}
|
||||
|
||||
shim.randomBytes = async (count) => {
|
||||
const randomBytes = await generateSecureRandom(count);
|
||||
let temp = [];
|
||||
|
@ -107,7 +107,7 @@ shim.fetchWithRetry = async function(fetchFn, options = null) {
|
||||
shim.nativeFetch_ = typeof fetch !== 'undefined' ? fetch : null;
|
||||
shim.fetch = () => { throw new Error('Not implemented'); }
|
||||
shim.FormData = typeof FormData !== 'undefined' ? FormData : null;
|
||||
shim.fs = null;
|
||||
shim.fsDriver = () => { throw new Error('Not implemented') }
|
||||
shim.FileApiDriverLocal = null;
|
||||
shim.readLocalFileBase64 = (path) => { throw new Error('Not implemented'); }
|
||||
shim.uploadBlob = () => { throw new Error('Not implemented'); }
|
||||
|
@ -10,7 +10,7 @@ const { time } = require('lib/time-utils.js');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const moment = require('moment');
|
||||
const JoplinError = require('lib/JoplinError');
|
||||
|
||||
class Synchronizer {
|
||||
|
||||
@ -27,7 +27,7 @@ class Synchronizer {
|
||||
|
||||
// Debug flags are used to test certain hard-to-test conditions
|
||||
// such as cancelling in the middle of a loop.
|
||||
this.debugFlags_ = [];
|
||||
this.testingHooks_ = [];
|
||||
|
||||
this.onProgress_ = function(s) {};
|
||||
this.progressReport_ = {};
|
||||
@ -279,7 +279,7 @@ class Synchronizer {
|
||||
const localResourceContentPath = result.path;
|
||||
await this.api().put(remoteContentPath, null, { path: localResourceContentPath, source: 'file' });
|
||||
} catch (error) {
|
||||
if (error && error.code === 'rejectedByTarget') {
|
||||
if (error && ['rejectedByTarget', 'fileNotFound'].indexOf(error.code) >= 0) {
|
||||
await handleCannotSyncItem(syncTargetId, local, error.message);
|
||||
action = null;
|
||||
} else {
|
||||
@ -303,11 +303,7 @@ class Synchronizer {
|
||||
|
||||
let canSync = true;
|
||||
try {
|
||||
if (this.debugFlags_.indexOf('rejectedByTarget') >= 0) {
|
||||
const error = new Error('Testing rejectedByTarget');
|
||||
error.code = 'rejectedByTarget';
|
||||
throw error;
|
||||
}
|
||||
if (this.testingHooks_.indexOf('rejectedByTarget') >= 0) throw new JoplinError('Testing rejectedByTarget', 'rejectedByTarget');
|
||||
const content = await ItemClass.serializeForSync(local);
|
||||
await this.api().put(path, content);
|
||||
} catch (error) {
|
||||
@ -449,7 +445,7 @@ class Synchronizer {
|
||||
this.logSyncOperation('fetchingTotal', null, null, 'Fetching delta items from sync target', remotes.length);
|
||||
|
||||
for (let i = 0; i < remotes.length; i++) {
|
||||
if (this.cancelling() || this.debugFlags_.indexOf('cancelDeltaLoop2') >= 0) {
|
||||
if (this.cancelling() || this.testingHooks_.indexOf('cancelDeltaLoop2') >= 0) {
|
||||
hasCancelled = true;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user