Skip to content

Commit

Permalink
Reconnect after session has timed out
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <jus@bitgrid.net>
  • Loading branch information
juliushaertl committed Jul 10, 2019
1 parent eb155ec commit e9e09b8
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 7 deletions.
4 changes: 3 additions & 1 deletion lib/Service/ApiService.php
Expand Up @@ -145,7 +145,7 @@ public function push($documentId, $sessionId, $sessionToken, $version, $steps, $
}
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 {
Expand Down Expand Up @@ -176,6 +176,8 @@ public function sync($documentId, $sessionId, $sessionToken, $version = 0, $auto
} 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([
Expand Down
4 changes: 4 additions & 0 deletions lib/Service/DocumentService.php
Expand Up @@ -237,6 +237,10 @@ public function autosave($documentId, $version, $autoaveDocument, $force = false
$file = $this->getFileByShareToken($token, $filePath);
}

if ($file === null) {
throw new NotFoundException();
}

if ($this->isReadOnly($file, $token)) {
return $document;
}
Expand Down
7 changes: 5 additions & 2 deletions src/EditorFactory.js
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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]
Expand Down
21 changes: 18 additions & 3 deletions src/components/EditorWrapper.vue
Expand Up @@ -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) => {
Expand All @@ -334,6 +344,11 @@ export default {
},
resolveUseServerVersion() {
this.forceRecreate = true
this.reconnect()
},
reconnect() {
this.forceRecreate = true
this.syncService.close()
this.syncService = null
Expand Down
11 changes: 11 additions & 0 deletions src/services/PollingBackend.js
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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()
})
Expand Down
6 changes: 5 additions & 1 deletion src/services/SyncService.js
Expand Up @@ -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 {
Expand Down

0 comments on commit e9e09b8

Please sign in to comment.