From b4e5f641e4dfdce5090f2d7aadf865f64d5bb6f3 Mon Sep 17 00:00:00 2001 From: Dmitriy Chukhin Date: Wed, 27 Jul 2016 21:39:57 -0400 Subject: [PATCH] bug 1260197 - handle spam and midair collision error messages --- kuma/static/js/wiki-edit.js | 37 +++++++++++++++++++++++-------------- kuma/wiki/forms.py | 19 +++++++++++++++---- kuma/wiki/views/edit.py | 8 ++++++++ 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/kuma/static/js/wiki-edit.js b/kuma/static/js/wiki-edit.js index 4a78e274e42..f54aacc96f3 100644 --- a/kuma/static/js/wiki-edit.js +++ b/kuma/static/js/wiki-edit.js @@ -496,7 +496,6 @@ var formURL = window.location.href; // submits to self console.log('posting this data: ', formData) - // ajax submit $.ajax({ url : formURL + '?async', type: "POST", @@ -528,16 +527,22 @@ // We also need to update the form's current_rev to // avoid triggering a conflict, since we just saved in // the background. - var responseRevision = JSON.parse(data)['new_revision_id']; - console.log('responseRevision: ', responseRevision); - // TODO: why are there multiple s? - $("input[id=id_current_rev]").val(responseRevision) - - // Clear the review comment - $('#id_comment').val(''); - - // Trigger a `mdn:save-success` event so dirtiness can be reset throughout the page - $form.trigger('mdn:save-success'); + console.log('data is: ', data) + var responseData = JSON.parse(data) + if (responseData['error'] == true) { + saveNotification.error(responseData['error_message']) + } else { + var responseRevision = JSON.parse(data)['new_revision_id']; + console.log('responseRevision: ', responseRevision); + // TODO: why are there multiple s? + $("input[id=id_current_rev]").val(responseRevision) + + // Clear the review comment + $('#id_comment').val(''); + + // Trigger a `mdn:save-success` event so dirtiness can be reset throughout the page + $form.trigger('mdn:save-success'); + } // Re-enable the form; it gets disabled to prevent double-POSTs $form.data('disabled', false).removeClass('disabled'); @@ -549,9 +554,13 @@ // console.log(jqXHR.status); // console.log(textStatus); // console.log(errorThrown); - var msg = "Publishing failed. Please copy and paste your changes into a safe place and try submitting the form using the 'Publish' button."; - - saveNotification.error(msg); + // Try to display the error that comes back from the server + try { + var errorMessage = JSON.parse(jqXHR['responseText'])['error_message'] + } catch (err) { + errorMessage = "Publishing failed. Please copy and paste your changes into a safe place and try submitting the form using the 'Publish' button."; + } + saveNotification.error(errorMessage); // saveNotification.error(msg, {closable: true, duration: 0}); // save draft diff --git a/kuma/wiki/forms.py b/kuma/wiki/forms.py index f72526308fa..608abe8eab1 100644 --- a/kuma/wiki/forms.py +++ b/kuma/wiki/forms.py @@ -17,6 +17,7 @@ import kuma.wiki.content from kuma.core.form_fields import StrippedCharField +from kuma.core.urlresolvers import reverse from kuma.spam.akismet import AkismetError from kuma.spam.forms import AkismetCheckFormMixin, AkismetSubmissionFormMixin @@ -64,8 +65,10 @@ SLUG_COLLIDES = _(u'Another document with this slug already exists.') OTHER_COLLIDES = _(u'Another document with this metadata already exists.') -MIDAIR_COLLISION = _(u'This document was modified while you were ' - u'editing it.') +MIDAIR_COLLISION = _(u'Publishing failed. Conflicting edit attempts detected. ' + u'Please copy and paste your edits to a safe place and ' + u'visit the revision history page ' + u'to see what was changed before making further edits.') MOVE_REQUIRED = _(u"Changing this document's slug requires " u"moving it and its children.") @@ -659,13 +662,21 @@ def clean_current_rev(self): if orig_ct != curr_ct: # Oops. Looks like the section did actually get # changed, so yeah this is a collision. - raise forms.ValidationError(MIDAIR_COLLISION) + url = reverse( + 'wiki.document_revisions', + kwargs={'document_path': self.instance.document.slug} + ) + raise forms.ValidationError(MIDAIR_COLLISION % {'url': url}) return current_rev else: # No section edit, so this is a flat-out collision. - raise forms.ValidationError(MIDAIR_COLLISION) + url = reverse( + 'wiki.document_revisions', + kwargs={'document_path': self.instance.document.slug} + ) + raise forms.ValidationError(MIDAIR_COLLISION % {'url': url}) except Document.DoesNotExist: # If there's no document yet, just bail. diff --git a/kuma/wiki/views/edit.py b/kuma/wiki/views/edit.py index 6e9f46112ac..19cd5cb6fcb 100644 --- a/kuma/wiki/views/edit.py +++ b/kuma/wiki/views/edit.py @@ -208,6 +208,14 @@ def edit(request, document_slug, document_locale, revision_id=None): if not rev_form.is_valid(): # Was there a mid-air collision? if 'current_rev' in rev_form._errors: + # If this was an Ajax POST, then return a JSONReponse + if is_async_submit: + data = { + "error": True, + "error_message": rev_form.errors['current_rev'], + "new_revision_id": curr_rev.id, + } + return JsonResponse(data=data, status=500) # Jump out to a function to escape indentation hell return _edit_document_collision( request, orig_rev, curr_rev, is_async_submit,