Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2019-07-10 19:52:35 +0300
committerGitHub <noreply@github.com>2019-07-10 19:52:35 +0300
commit2593f469c3995d91baea4192a0295ee349689342 (patch)
tree2e6a0c1dbd1d22802f960efc3089e89639fa88cf
parenteb155ec1e94f33574d990fb33459b91bce311e18 (diff)
parent31ad3a0d765e0dbbbe099dc5f683aeea1a25d884 (diff)
Reconnect after session has timed out (#154)
Reconnect after session has timed out
-rw-r--r--lib/Service/ApiService.php4
-rw-r--r--lib/Service/DocumentService.php4
-rw-r--r--src/EditorFactory.js7
-rw-r--r--src/components/EditorWrapper.vue20
-rw-r--r--src/public.js2
-rw-r--r--src/services/PollingBackend.js11
-rw-r--r--src/services/SyncService.js6
7 files changed, 46 insertions, 8 deletions
diff --git a/lib/Service/ApiService.php b/lib/Service/ApiService.php
index 83a7a8124..c6a35c610 100644
--- a/lib/Service/ApiService.php
+++ b/lib/Service/ApiService.php
@@ -145,7 +145,7 @@ class ApiService {
}
return new DataResponse($steps);
}
- return new DataResponse([], 500);
+ return new DataResponse([], 403);
}
public function sync($documentId, $sessionId, $sessionToken, $version = 0, $autosaveContent = null, bool $force = false, bool $manualSave = false, $token = null): DataResponse {
@@ -176,6 +176,8 @@ class ApiService {
} catch (LockedException $e) {
// Ignore locked exception since it might happen due to an autosave action happening at the same time
}
+ } catch (NotFoundException $e) {
+ return new DataResponse([], 404);
} catch (Exception $e) {
$this->logger->logException($e);
return new DataResponse([
diff --git a/lib/Service/DocumentService.php b/lib/Service/DocumentService.php
index f2784da5c..31dcb6910 100644
--- a/lib/Service/DocumentService.php
+++ b/lib/Service/DocumentService.php
@@ -237,6 +237,10 @@ class DocumentService {
$file = $this->getFileByShareToken($token, $filePath);
}
+ if ($file === null) {
+ throw new NotFoundException();
+ }
+
if ($this->isReadOnly($file, $token)) {
return $document;
}
diff --git a/src/EditorFactory.js b/src/EditorFactory.js
index e0cbd3206..32fbf12be 100644
--- a/src/EditorFactory.js
+++ b/src/EditorFactory.js
@@ -101,7 +101,7 @@ const createEditor = ({ content, onUpdate, extensions, enableRichEditing, langua
const markdownit = MarkdownIt('commonmark', { html: false, breaks: false })
.enable('strikethrough')
-const SerializeException = (message) => {
+const SerializeException = function(message) {
this.message = message
}
const createMarkdownSerializer = (_nodes, _marks) => {
@@ -135,7 +135,10 @@ const createMarkdownSerializer = (_nodes, _marks) => {
const serializePlainText = (tiptap) => {
const doc = tiptap.getJSON()
- if (doc.content.length !== 1 || doc.content[0].content.length !== 1) {
+ if (doc.content.length !== 1 || typeof doc.content[0].content === 'undefined' || doc.content[0].content.length !== 1) {
+ if (doc.content[0].type === 'code_block' && typeof doc.content[0].content === 'undefined') {
+ return ''
+ }
throw new SerializeException('Failed to serialize document to plain text')
}
const codeBlock = doc.content[0].content[0]
diff --git a/src/components/EditorWrapper.vue b/src/components/EditorWrapper.vue
index 0f606378c..f9edfa48b 100644
--- a/src/components/EditorWrapper.vue
+++ b/src/components/EditorWrapper.vue
@@ -305,14 +305,24 @@ export default {
this.document = document
})
.on('error', (error, data) => {
+ this.tiptap.setOptions({ editable: false })
if (error === ERROR_TYPE.SAVE_COLLISSION && (!this.syncError || this.syncError.type !== ERROR_TYPE.SAVE_COLLISSION)) {
this.initialLoading = true
this.syncError = {
- type: ERROR_TYPE.SAVE_COLLISSION,
+ type: error,
data: data
}
- this.tiptap.setOptions({ editable: false })
-
+ }
+ if (error === ERROR_TYPE.CONNECTION_FAILED) {
+ this.initialLoading = false
+ // FIXME: ideally we just try to reconnect in the service, so we don't loose steps
+ OC.Notification.showTemporary('Connection failed, reconnecting')
+ this.reconnect()
+ }
+ if (error === ERROR_TYPE.SOURCE_NOT_FOUND) {
+ this.initialLoading = false
+ OC.Notification.showTemporary('Source not found')
+ this.$emit('close')
}
})
.on('stateChange', (state) => {
@@ -335,6 +345,10 @@ export default {
resolveUseServerVersion() {
this.forceRecreate = true
+ this.reconnect()
+ },
+
+ reconnect() {
this.syncService.close()
this.syncService = null
this.tiptap.destroy()
diff --git a/src/public.js b/src/public.js
index aa87dfee8..54a491c3a 100644
--- a/src/public.js
+++ b/src/public.js
@@ -34,7 +34,7 @@ documentReady(() => {
props: {
active: true,
shareToken: sharingToken,
- mimetype: mimetype
+ mime: mimetype
}
})
})
diff --git a/src/services/PollingBackend.js b/src/services/PollingBackend.js
index b650516f0..a41d1353f 100644
--- a/src/services/PollingBackend.js
+++ b/src/services/PollingBackend.js
@@ -145,6 +145,8 @@ class PollingBackend {
this._authority.emit('error', ERROR_TYPE.SAVE_COLLISSION, {
outsideChange: e.response.data.outsideChange
})
+ } else if (e.response.status === 403) {
+ this._authority.emit('error', ERROR_TYPE.CONNECTION_FAILED, {})
} else {
console.error('Failed to fetch steps due to other reason', e)
}
@@ -179,6 +181,15 @@ class PollingBackend {
}).catch((e) => {
console.error('failed to apply steps due to collission, retrying')
this.lock = false
+ if (!e.response) {
+ throw e
+ }
+ // Only emit conflict event if we have synced until the latest version
+ if (e.response.status === 403 && e.response.data.document.currentVersion === this._authority.document.currentVersion) {
+ this._authority.emit('error', ERROR_TYPE.PUSH_FAILURE, {})
+ OC.Notification.showTemporary('Changes could not be sent yet')
+ }
+
this.fetchSteps()
this.carefulRetry()
})
diff --git a/src/services/SyncService.js b/src/services/SyncService.js
index 306ffc5f8..2d7a95829 100644
--- a/src/services/SyncService.js
+++ b/src/services/SyncService.js
@@ -42,7 +42,11 @@ const ERROR_TYPE = {
*/
PUSH_FAILURE: 1,
- LOAD_ERROR: 2
+ LOAD_ERROR: 2,
+
+ CONNECTION_FAILED: 3,
+
+ SOURCE_NOT_FOUND: 4
}
class SyncService {