Mholloway has uploaded a new change for review. https://gerrit.wikimedia.org/r/318112
Change subject: Retrofit editing ...................................................................... Retrofit editing Change-Id: I54e551b3f4802350740db5450f018549373558f8 --- D app/src/androidTest/java/org/wikipedia/editing/EditTaskTest.java A app/src/androidTest/java/org/wikipedia/editing/EditTest.java A app/src/main/java/org/wikipedia/editing/Edit.java M app/src/main/java/org/wikipedia/editing/EditClient.java M app/src/main/java/org/wikipedia/editing/EditSectionActivity.java 5 files changed, 374 insertions(+), 253 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia refs/changes/12/318112/1 diff --git a/app/src/androidTest/java/org/wikipedia/editing/EditTaskTest.java b/app/src/androidTest/java/org/wikipedia/editing/EditTaskTest.java deleted file mode 100644 index 7b5d84f..0000000 --- a/app/src/androidTest/java/org/wikipedia/editing/EditTaskTest.java +++ /dev/null @@ -1,182 +0,0 @@ -package org.wikipedia.editing; - -import android.support.annotation.NonNull; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.wikipedia.WikipediaApp; -import org.wikipedia.dataclient.WikiSite; -import org.wikipedia.page.PageTitle; -import org.wikipedia.testlib.TestLatch; - -import static android.support.test.InstrumentationRegistry.getTargetContext; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class EditTaskTest { - private static final WikiSite TEST_WIKI = WikiSite.forLanguageCode("test"); - - private static final String ABUSE_FILTER_ERROR_PAGE_TITLE = "Test_page_for_app_testing/AbuseFilter"; - - @Before - public void setUp() { - // Cookies for a logged in session cannot be used with the anonymous edit token. - app().getCookieManager().clearAllCookies(); - } - - @Test - public void testEdit() { - PageTitle title = new PageTitle(null, "Test_page_for_app_testing/Section1", TEST_WIKI); - String wikitext = "== Section 2 ==\n\nEditing section INSERT RANDOM & HERE test at " - + System.currentTimeMillis(); - final int sectionId = 3; - - EditingResult result = Subject.execute(title, wikitext, sectionId); - assertThat(result, instanceOf(SuccessEditResult.class)); - } - - @Test - public void testCaptcha() { - PageTitle title = new PageTitle(null, "Test_page_for_app_testing/Captcha", TEST_WIKI); - String wikitext = "== Section 2 ==\n\nEditing by inserting an external link https://" - + System.currentTimeMillis(); - - EditingResult result = Subject.execute(title, wikitext); - validateCaptcha(result); - } - - /** - * Test handling of abuse filter warnings which warn users about making edits of a certain kind. - * - * Type: warn - * Action: editing any userspace page while logged out - * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/94 - */ - @Test - public void testAbuseFilterTriggerWarn() { - PageTitle title = new PageTitle(null, "User:Yuvipandaaaaaaaa", TEST_WIKI); - - // Rule 94 is only a warning so the initial attempt may be successful. The second is - // guaranteed to be a warning if different content is used. @FlakyTest(tolerance = 2) - // doesn't work with JUnit 4. - EditingResult result = null; - for (int i = 0; !(result instanceof AbuseFilterEditResult) && i < 2; ++i) { - String wikitext = "Testing Abusefilter by simply editing this page. Triggering rule 94 at " - + System.nanoTime(); - result = Subject.execute(title, wikitext); - } - - assertThat(result, instanceOf(AbuseFilterEditResult.class)); - // todo: test against a warning, not an error. Rule 94 is currently returning - // abusefilter-disallowed instead of abusefilter-warning. EditTask needs to be - // reworked to a data client that can consume mock data - //noinspection ConstantConditions - assertThat(((AbuseFilterEditResult) result).getType(), is(AbuseFilterEditResult.TYPE_ERROR)); - } - - /** - * Test handling of abuse filter errors which completely disallow edits of a certain kind. - * - * Type: disallow - * Action: adding string "poop" to page text - * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/2 - */ - @Test - public void testAbuseFilterTriggerStop() { - PageTitle title = new PageTitle(null, ABUSE_FILTER_ERROR_PAGE_TITLE, TEST_WIKI); - String wikitext = "== Section 2 ==\n\nTriggering AbuseFilter number 2 by saying poop many times at " - + System.currentTimeMillis(); - - EditingResult result = Subject.execute(title, wikitext); - assertThat(result, instanceOf(AbuseFilterEditResult.class)); - assertThat(((AbuseFilterEditResult) result).getType(), is(AbuseFilterEditResult.TYPE_ERROR)); - } - - /** - * Test the app's handling of the abuse filter emitting arbitrary error codes. - * - * Type: warn - * Action: adding string "appcrashtest" to page text - * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/152 - */ - @Test - public void testAbuseFilterTriggerStopOnArbitraryErrorCode() { - PageTitle title = new PageTitle(null, ABUSE_FILTER_ERROR_PAGE_TITLE, TEST_WIKI); - String wikitext = "== Section 2 ==\n\nTriggering AbuseFilter number 152 by saying appcrashtest many times at " - + System.currentTimeMillis(); - - EditingResult result = Subject.execute(title, wikitext); - assertThat(result, instanceOf(AbuseFilterEditResult.class)); - assertThat(((AbuseFilterEditResult) result).getType(), is(AbuseFilterEditResult.TYPE_ERROR)); - } - - private void validateCaptcha(EditingResult result) { - assertThat(result, instanceOf(CaptchaResult.class)); - CaptchaResult captchaResult = (CaptchaResult) result; - String url = captchaResult.getCaptchaUrl(TEST_WIKI); - assertThat(isValidCaptchaUrl(url), is(true)); - } - - private boolean isValidCaptchaUrl(String url) { - return url.startsWith(getNetworkProtocol() - + "://test.wikipedia.org/w/index.php?title=Special:Captcha/image"); - } - - private String getNetworkProtocol() { - return app().getWikiSite().scheme(); - } - - private WikipediaApp app() { - return WikipediaApp.getInstance(); - } - - private static class Subject extends EditTask { - private static final int DEFAULT_SECTION_ID = 0; - - // https://www.mediawiki.org/wiki/Manual:Edit_token#The_edit_token_suffix - private static final String ANONYMOUS_TOKEN = "+\\"; - - private static final String DEFAULT_SUMMARY = ""; - - public static EditingResult execute(PageTitle title, String sectionWikitext) { - return execute(title, sectionWikitext, DEFAULT_SECTION_ID); - } - - public static EditingResult execute(PageTitle title, String sectionWikitext, int sectionId) { - return execute(title, sectionWikitext, sectionId, ANONYMOUS_TOKEN); - } - - public static EditingResult execute(PageTitle title, String sectionWikitext, int sectionId, - String token) { - Subject subject = new Subject(title, sectionWikitext, sectionId, token); - subject.execute(); - return subject.await(); - } - - @NonNull private final TestLatch latch = new TestLatch(); - private EditingResult result; - - Subject(PageTitle title, String sectionWikitext, int sectionId, String token) { - super(getTargetContext(), title, sectionWikitext, sectionId, token, DEFAULT_SUMMARY, - false); - } - - @Override - public void onFinish(EditingResult result) { - super.onFinish(result); - this.result = result; - latch.countDown(); - } - - public EditingResult await() { - latch.await(); - return result; - } - } -} diff --git a/app/src/androidTest/java/org/wikipedia/editing/EditTest.java b/app/src/androidTest/java/org/wikipedia/editing/EditTest.java new file mode 100644 index 0000000..09c13bd --- /dev/null +++ b/app/src/androidTest/java/org/wikipedia/editing/EditTest.java @@ -0,0 +1,190 @@ +package org.wikipedia.editing; + +import android.support.annotation.NonNull; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.wikipedia.WikipediaApp; +import org.wikipedia.dataclient.WikiSite; +import org.wikipedia.page.PageTitle; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(AndroidJUnit4.class) +public class EditTest { + private static final WikiSite TEST_WIKI_SITE = new WikiSite("test.wikipedia.org"); + private static final String ABUSE_FILTER_ERROR_PAGE_TITLE = "Test_page_for_app_testing/AbuseFilter"; + private static final int DEFAULT_SECTION_ID = 0; + // https://www.mediawiki.org/wiki/Manual:Edit_token#The_edit_token_suffix + private static final String ANONYMOUS_TOKEN = "+\\"; + private static final String DEFAULT_SUMMARY = ""; + + @Before + public void setUp() { + // Cookies for a logged in session cannot be used with the anonymous edit token. + app().getCookieManager().clearAllCookies(); + } + + @Test + public void testEdit() { + PageTitle title = new PageTitle(null, "Test_page_for_app_testing/Section1", TEST_WIKI_SITE); + String wikitext = "== Section 2 ==\n\nEditing section INSERT RANDOM & HERE test at " + + System.currentTimeMillis(); + final int sectionId = 3; + + service.edit(TEST_WIKI_SITE, title, sectionId, wikitext, ANONYMOUS_TOKEN, DEFAULT_SUMMARY, + false, null, null, new Edit.Callback() { + @Override + public void success(@NonNull EditingResult result) { + assertThat(result, instanceOf(SuccessEditResult.class)); + } + + @Override + public void failure(@NonNull Throwable caught) { + throw new RuntimeException(caught); + } + }); + } + + @Test + public void testCaptcha() { + PageTitle title = new PageTitle(null, "Test_page_for_app_testing/Captcha", TEST_WIKI_SITE); + String wikitext = "== Section 2 ==\n\nEditing by inserting an external link https://" + + System.currentTimeMillis(); + + service.edit(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext, ANONYMOUS_TOKEN, + DEFAULT_SUMMARY, false, null, null, new Edit.Callback() { + @Override + public void success(@NonNull EditingResult result) { + validateCaptcha(result); + } + + @Override + public void failure(@NonNull Throwable caught) { + throw new RuntimeException(caught); + } + }); + } + + /** + * Test handling of abuse filter warnings which warn users about making edits of a certain kind. + * + * Type: warn + * Action: editing any userspace page while logged out + * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/94 + */ + @Test + public void testAbuseFilterTriggerWarn() { + PageTitle title = new PageTitle(null, "User:Yuvipandaaaaaaaa", TEST_WIKI_SITE); + + // Rule 94 is only a warning so the initial attempt may be successful. The second is + // guaranteed to be a warning if different content is used. @FlakyTest(tolerance = 2) + // doesn't work with JUnit 4. + for (int i = 0; i < 2; ++i) { + String wikitext = "Testing Abusefilter by simply editing this page. Triggering rule 94" + + "at " + System.nanoTime(); + + service.edit(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext, ANONYMOUS_TOKEN, + DEFAULT_SUMMARY, false, null, null, new Edit.Callback() { + @Override + public void success(@NonNull EditingResult result) { + if (!(result instanceof SuccessEditResult)) { + assertThat(result, instanceOf(AbuseFilterEditResult.class)); + //noinspection ConstantConditions + assertThat(((AbuseFilterEditResult) result).getType(), + is(AbuseFilterEditResult.TYPE_WARNING)); + } + } + + @Override + public void failure(@NonNull Throwable caught) { + throw new RuntimeException(caught); + } + }); + } + } + + /** + * Test handling of abuse filter errors which completely disallow edits of a certain kind. + * + * Type: disallow + * Action: adding string "poop" to page text + * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/2 + */ + @Test + public void testAbuseFilterTriggerStop() { + PageTitle title = new PageTitle(null, ABUSE_FILTER_ERROR_PAGE_TITLE, TEST_WIKI_SITE); + String wikitext = "== Section 2 ==\n\nTriggering AbuseFilter number 2 by saying poop many" + + "times at " + System.currentTimeMillis(); + + service.edit(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext, ANONYMOUS_TOKEN, + DEFAULT_SUMMARY, false, null, null, new Edit.Callback() { + @Override + public void success(@NonNull EditingResult result) { + assertThat(result, instanceOf(AbuseFilterEditResult.class)); + assertThat(((AbuseFilterEditResult) result).getType(), + is(AbuseFilterEditResult.TYPE_ERROR)); + } + + @Override + public void failure(@NonNull Throwable caught) { + throw new RuntimeException(caught); + } + }); + } + + /** + * Test the app's handling of the abuse filter emitting arbitrary error codes. + * + * Type: warn + * Action: adding string "appcrashtest" to page text + * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/152 + */ + @Test + public void testAbuseFilterTriggerStopOnArbitraryErrorCode() { + PageTitle title = new PageTitle(null, ABUSE_FILTER_ERROR_PAGE_TITLE, TEST_WIKI_SITE); + String wikitext = "== Section 2 ==\n\nTriggering AbuseFilter number 152 by saying" + + "appcrashtest many times at " + System.currentTimeMillis(); + + service.edit(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext, ANONYMOUS_TOKEN, + DEFAULT_SUMMARY, false, null, null, new Edit.Callback() { + @Override + public void success(@NonNull EditingResult result) { + assertThat(result, instanceOf(AbuseFilterEditResult.class)); + assertThat(((AbuseFilterEditResult) result).getType(), + is(AbuseFilterEditResult.TYPE_WARNING)); + } + + @Override + public void failure(@NonNull Throwable caught) { + throw new RuntimeException(caught); + } + }); + } + + private void validateCaptcha(EditingResult result) { + assertThat(result, instanceOf(CaptchaResult.class)); + CaptchaResult captchaResult = (CaptchaResult) result; + String url = captchaResult.getCaptchaUrl(TEST_WIKI_SITE); + assertThat(isValidCaptchaUrl(url), is(true)); + } + + private boolean isValidCaptchaUrl(String url) { + return url.startsWith(getNetworkProtocol() + + "://test.wikipedia.org/w/index.php?title=Special:Captcha/image"); + } + + private String getNetworkProtocol() { + return app().getWikiSite().scheme(); + } + + private WikipediaApp app() { + return WikipediaApp.getInstance(); + } + + private EditClient service = new EditClient(); +} diff --git a/app/src/main/java/org/wikipedia/editing/Edit.java b/app/src/main/java/org/wikipedia/editing/Edit.java new file mode 100644 index 0000000..6a84a66 --- /dev/null +++ b/app/src/main/java/org/wikipedia/editing/Edit.java @@ -0,0 +1,58 @@ +package org.wikipedia.editing; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +public class Edit { + @SuppressWarnings("unused,NullableProblems") @NonNull private Result edit; + @NonNull protected Result edit() { + return edit; + } + + protected class Result { + @Nullable private String result; + @Nullable protected String status() { + return result; + } + + private int newrevid; + protected int newRevId() { + return newrevid; + } + + @Nullable private Captcha captcha; + @Nullable protected Captcha captcha() { + return captcha; + } + + @Nullable private String code; + @Nullable protected String code() { + return code; + } + + protected boolean hasErrorCode() { + return code != null; + } + + @Nullable private String spamblacklist; + @Nullable protected String spamblacklist() { + return spamblacklist; + } + + protected boolean hasSpamBlacklistResponse() { + return spamblacklist != null; + } + } + + protected class Captcha { + @SuppressWarnings("unused,NullableProblems") @NonNull private String id; + @NonNull protected String id() { + return id; + } + } + + public interface Callback { + void success(@NonNull EditingResult result); + void failure(@NonNull Throwable caught); + } +} diff --git a/app/src/main/java/org/wikipedia/editing/EditClient.java b/app/src/main/java/org/wikipedia/editing/EditClient.java index ad27f73..00d57ac 100644 --- a/app/src/main/java/org/wikipedia/editing/EditClient.java +++ b/app/src/main/java/org/wikipedia/editing/EditClient.java @@ -1,13 +1,17 @@ package org.wikipedia.editing; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import org.json.JSONException; +import org.json.JSONObject; import org.wikipedia.dataclient.WikiSite; import org.wikipedia.dataclient.retrofit.MwCachedService; import org.wikipedia.dataclient.retrofit.RetrofitException; +import org.wikipedia.json.GsonMarshaller; import org.wikipedia.json.GsonUnmarshaller; import org.wikipedia.page.PageTitle; import org.wikipedia.server.mwapi.ApiResponsePage; @@ -18,6 +22,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import retrofit2.Call; import retrofit2.Callback; @@ -56,6 +61,50 @@ public String editTokenSync(@NonNull final WikiSite wiki) throws IOException { Call<EditToken> call = cachedService.service(wiki).editToken(); return call.execute().body().query().tokens().token(); + } + + @SuppressWarnings("checkstyle:parameternumber") + public void edit(@NonNull final WikiSite wiki, @NonNull final PageTitle title, + final int section, @NonNull final String text, @NonNull final String token, + @NonNull final String summary, final boolean loggedIn, + @Nullable final String captchaId, @Nullable final String captchaWord, + @NonNull final Edit.Callback cb) { + Call<Edit> call = cachedService.service(wiki).edit("edit", "json", title.getPrefixedText(), + section, text, token, summary, loggedIn ? "user" : null, captchaId, captchaWord); + call.enqueue(new Callback<Edit>() { + @Override + public void onResponse(Call<Edit> call, Response<Edit> response) { + if (response.isSuccessful()) { + Edit.Result result = response.body().edit(); + if ("Success".equals(result.status())) { + try { + // TODO: remove when the server reflects the updated page content + // immediately after submitting the edit, instead of a short while after. + Thread.sleep(TimeUnit.SECONDS.toMillis(2)); + cb.success(new SuccessEditResult(result.newRevId())); + } catch (InterruptedException e) { + cb.failure(e); + } + } else if (result.hasErrorCode()) { + try { + JSONObject json = new JSONObject(GsonMarshaller.marshal(result)); + cb.success(new AbuseFilterEditResult(json)); + } catch (JSONException e) { + cb.failure(e); + } + } else if (result.hasSpamBlacklistResponse()) { + cb.success(new SpamBlacklistEditResult(result.spamblacklist())); + } else { + cb.failure(new RuntimeException("Received unrecognized edit response")); + } + } + } + + @Override + public void onFailure(Call<Edit> call, Throwable t) { + + } + }); } public void wikitext(@NonNull final WikiSite wiki, @NonNull final PageTitle title, @@ -113,6 +162,20 @@ @GET("w/api.php?action=query&format=json&meta=tokens&type=csrf") Call<EditToken> editToken(); + @FormUrlEncoded + @POST("w/api.php") + @SuppressWarnings("checkstyle:parameternumber") + Call<Edit> edit(@NonNull @Field("action") String action, + @NonNull @Field("format") String format, + @NonNull @Field("title") String title, + @Field("section") int section, + @NonNull @Field("text") String text, + @NonNull @Field("token") String token, + @NonNull @Field("summary") String summary, + @Nullable @Field("assert") String user, + @Nullable @Field("captchaId") String captchaId, + @Nullable @Field("captchaWord") String captchaWord); + @GET("w/api.php?action=query&format=json&prop=revisions&rvprop=content&rvlimit=1") Call<Wikitext> wikitext(@NonNull @Query("titles") String title, diff --git a/app/src/main/java/org/wikipedia/editing/EditSectionActivity.java b/app/src/main/java/org/wikipedia/editing/EditSectionActivity.java index c0f6111..4ea3ede 100644 --- a/app/src/main/java/org/wikipedia/editing/EditSectionActivity.java +++ b/app/src/main/java/org/wikipedia/editing/EditSectionActivity.java @@ -27,9 +27,7 @@ import android.widget.ScrollView; import android.widget.TextView; -import org.mediawiki.api.json.Api; import org.mediawiki.api.json.ApiException; -import org.mediawiki.api.json.RequestBuilder; import org.wikipedia.Constants; import org.wikipedia.R; import org.wikipedia.ViewAnimations; @@ -280,79 +278,73 @@ // Summaries are plaintext, so remove any HTML that's made its way into the summary summaryText = StringUtil.fromHtml(summaryText).toString(); - new EditTask(EditSectionActivity.this, title, sectionText.getText().toString(), - sectionID, token, summaryText, User.isLoggedIn()) { - @Override - public void onBeforeExecute() { - if (!isFinishing()) { - progressDialog.show(); - } - } + if (!isFinishing()) { + progressDialog.show(); + } - @Override - public RequestBuilder buildRequest(Api api) { - return captchaHandler.populateBuilder(super.buildRequest(api)); - } + apiService.edit(title.getWikiSite(), title, sectionID, + sectionText.getText().toString(), token, summaryText, User.isLoggedIn(), + captchaHandler.isActive() ? captchaHandler.captchaId() : "null", + captchaHandler.isActive() ? captchaHandler.captchaWord() : "null", + new Edit.Callback() { + @Override + public void success(@NonNull EditingResult result) { + if (isFinishing() || !progressDialog.isShowing()) { + // no longer attached to activity! + return; + } + if (result instanceof SuccessEditResult) { + funnel.logSaved(((SuccessEditResult) result).getRevID()); + progressDialog.dismiss(); - @Override - public void onCatch(Throwable caught) { - if (isFinishing() || !progressDialog.isShowing()) { - // no longer attached to activity! - return; - } - if (caught instanceof ApiException) { - // This is a fairly standard editing exception. Handle it appropriately. - handleEditingException((ApiException) caught); - } else { - // If it's not an API exception, we have no idea what's wrong. - // Show the user a generic error message. - L.w("Caught " + caught.toString()); - showRetryDialog(); - } - } - - @Override - public void onFinish(EditingResult result) { - if (isFinishing() || !progressDialog.isShowing()) { - // no longer attached to activity! - return; - } - if (result instanceof SuccessEditResult) { - funnel.logSaved(((SuccessEditResult) result).getRevID()); - progressDialog.dismiss(); - - //Build intent that includes the section we were editing, so we can scroll to it later - Intent data = new Intent(); - data.putExtra(EXTRA_SECTION_ID, sectionID); - setResult(EditHandler.RESULT_REFRESH_PAGE, data); - hideSoftKeyboard(EditSectionActivity.this); - finish(); - } else if (result instanceof CaptchaResult) { - if (captchaHandler.isActive()) { - // Captcha entry failed! - funnel.logCaptchaFailure(); + //Build intent that includes the section we were editing, so we can scroll to it later + Intent data = new Intent(); + data.putExtra(EXTRA_SECTION_ID, sectionID); + setResult(EditHandler.RESULT_REFRESH_PAGE, data); + hideSoftKeyboard(EditSectionActivity.this); + finish(); + } else if (result instanceof CaptchaResult) { + if (captchaHandler.isActive()) { + // Captcha entry failed! + funnel.logCaptchaFailure(); + } + captchaHandler.handleCaptcha(null, (CaptchaResult) result); + funnel.logCaptchaShown(); + } else if (result instanceof AbuseFilterEditResult) { + abusefilterEditResult = (AbuseFilterEditResult) result; + handleAbuseFilter(); + if (abusefilterEditResult.getType() == AbuseFilterEditResult.TYPE_ERROR) { + editPreviewFragment.hide(); + } + } else if (result instanceof SpamBlacklistEditResult) { + FeedbackUtil.showMessage(EditSectionActivity.this, + R.string.editing_error_spamblacklist); + progressDialog.dismiss(); + editPreviewFragment.hide(); + } else { + funnel.logError(result.getResult()); + // Expand to do everything. + failure(new Throwable()); + } } - captchaHandler.handleCaptcha(null, (CaptchaResult) result); - funnel.logCaptchaShown(); - } else if (result instanceof AbuseFilterEditResult) { - abusefilterEditResult = (AbuseFilterEditResult) result; - handleAbuseFilter(); - if (abusefilterEditResult.getType() == AbuseFilterEditResult.TYPE_ERROR) { - editPreviewFragment.hide(); - } - } else if (result instanceof SpamBlacklistEditResult) { - FeedbackUtil.showMessage(EditSectionActivity.this, - R.string.editing_error_spamblacklist); - progressDialog.dismiss(); - editPreviewFragment.hide(); - } else { - funnel.logError(result.getResult()); - // Expand to do everything. - onCatch(null); - } - } - }.execute(); + @Override + public void failure(@NonNull Throwable caught) { + if (isFinishing() || !progressDialog.isShowing()) { + // no longer attached to activity! + return; + } + if (caught instanceof ApiException) { + // This is a fairly standard editing exception. Handle it appropriately. + handleEditingException((ApiException) caught); + } else { + // If it's not an API exception, we have no idea what's wrong. + // Show the user a generic error message. + L.w("Caught " + caught.toString()); + showRetryDialog(); + } + } + }); } @Override -- To view, visit https://gerrit.wikimedia.org/r/318112 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I54e551b3f4802350740db5450f018549373558f8 Gerrit-PatchSet: 1 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Mholloway <mhollo...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits