Bug 1291821 - Simplify onFetchFailed, clean up some exception code r=rnewman draft
authorGrisha Kruglov <gkruglov@mozilla.com>
Tue, 11 Oct 2016 19:29:46 -0700
changeset 489487 fb565ed391b721f485f9be74ec3a7986bbc1dfd6
parent 489486 e2fdf70d6db6e242e65b788dcb6a09f975b5124b
child 489488 0f48a86e5d6861ffc217bd8c69c154e37c6fd871
push id46825
push usergkruglov@mozilla.com
push dateFri, 24 Feb 2017 21:13:39 +0000
reviewersrnewman
bugs1291821
milestone54.0a1
Bug 1291821 - Simplify onFetchFailed, clean up some exception code r=rnewman MozReview-Commit-ID: 11sIAPCfLWk
mobile/android/services/src/main/java/org/mozilla/gecko/sync/middleware/Crypto5MiddlewareRepositorySession.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/InactiveSessionException.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/InvalidRequestException.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/RepositorySession.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/Server11RepositorySession.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/AndroidBrowserRepositorySession.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/FennecTabsRepository.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/FormHistoryRepositorySession.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/PasswordsRepositorySession.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/delegates/DeferredRepositorySessionFetchRecordsDelegate.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/delegates/RepositorySessionFetchRecordsDelegate.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/downloaders/BatchingDownloader.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/synchronizer/RecordsChannel.java
mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/DefaultFetchDelegate.java
mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/ExpectInvalidRequestFetchDelegate.java
mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessFetchDelegate.java
mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/testhelpers/WBORepository.java
mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/SynchronizerHelpers.java
mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/helpers/ExpectSuccessRepositorySessionFetchRecordsDelegate.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/background/testhelpers/WBORepository.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/downloaders/BatchingDownloaderTest.java
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/middleware/Crypto5MiddlewareRepositorySession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/middleware/Crypto5MiddlewareRepositorySession.java
@@ -74,41 +74,41 @@ public class Crypto5MiddlewareRepository
 
     DecryptingTransformingFetchDelegate(RepositorySessionFetchRecordsDelegate next, KeyBundle bundle, RecordFactory recordFactory) {
       this.next = next;
       this.keyBundle = bundle;
       this.recordFactory = recordFactory;
     }
 
     @Override
-    public void onFetchFailed(Exception ex, Record record) {
-      next.onFetchFailed(ex, record);
+    public void onFetchFailed(Exception ex) {
+      next.onFetchFailed(ex);
     }
 
     @Override
     public void onFetchedRecord(Record record) {
       CryptoRecord r;
       try {
         r = (CryptoRecord) record;
       } catch (ClassCastException e) {
-        next.onFetchFailed(e, record);
+        next.onFetchFailed(e);
         return;
       }
       r.keyBundle = keyBundle;
       try {
         r.decrypt();
       } catch (Exception e) {
-        next.onFetchFailed(e, r);
+        next.onFetchFailed(e);
         return;
       }
       Record transformed;
       try {
         transformed = this.recordFactory.createRecord(r);
       } catch (Exception e) {
-        next.onFetchFailed(e, r);
+        next.onFetchFailed(e);
         return;
       }
       next.onFetchedRecord(transformed);
     }
 
     @Override
     public void onFetchCompleted(final long fetchEnd) {
       next.onFetchCompleted(fetchEnd);
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/InactiveSessionException.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/InactiveSessionException.java
@@ -5,13 +5,17 @@
 package org.mozilla.gecko.sync.repositories;
 
 import org.mozilla.gecko.sync.SyncException;
 
 public class InactiveSessionException extends SyncException {
 
   private static final long serialVersionUID = 537241160815940991L;
 
+  public InactiveSessionException() {
+    super();
+  }
+
   public InactiveSessionException(Exception ex) {
     super(ex);
   }
 
 }
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/InvalidRequestException.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/InvalidRequestException.java
@@ -5,12 +5,12 @@
 package org.mozilla.gecko.sync.repositories;
 
 import org.mozilla.gecko.sync.SyncException;
 
 public class InvalidRequestException extends SyncException {
 
   private static final long serialVersionUID = 4502951350743608243L;
 
-  public InvalidRequestException(Exception ex) {
-    super(ex);
+  public InvalidRequestException() {
+    super();
   }
 }
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/RepositorySession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/RepositorySession.java
@@ -275,24 +275,24 @@ public abstract class RepositorySession 
 
   /**
    * Run the provided command if we're active and our delegate queue
    * is not shut down.
    */
   protected synchronized void executeDelegateCommand(Runnable command)
       throws InactiveSessionException {
     if (!isActive() || delegateQueue.isShutdown()) {
-      throw new InactiveSessionException(null);
+      throw new InactiveSessionException();
     }
     delegateQueue.execute(command);
   }
 
   public synchronized void ensureActive() throws InactiveSessionException {
     if (!isActive()) {
-      throw new InactiveSessionException(null);
+      throw new InactiveSessionException();
     }
   }
 
   public synchronized boolean isActive() {
     return status == SessionStatus.ACTIVE;
   }
 
   public synchronized SessionStatus getStatus() {
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/Server11RepositorySession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/Server11RepositorySession.java
@@ -60,17 +60,17 @@ public class Server11RepositorySession e
   public void fetch(String[] guids,
                     RepositorySessionFetchRecordsDelegate delegate) {
     this.downloader.fetch(guids, delegate);
   }
 
   @Override
   public void wipe(RepositorySessionWipeDelegate delegate) {
     if (!isActive()) {
-      delegate.onWipeFailed(new InactiveSessionException(null));
+      delegate.onWipeFailed(new InactiveSessionException());
       return;
     }
     // TODO: implement wipe.
   }
 
   @Override
   public void store(Record record) throws NoStoreDelegateException {
     if (storeDelegate == null) {
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/AndroidBrowserRepositorySession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/AndroidBrowserRepositorySession.java
@@ -204,17 +204,17 @@ public abstract class AndroidBrowserRepo
                               RepositorySessionGuidsSinceDelegate delegate) {
       this.timestamp = timestamp;
       this.delegate = delegate;
     }
 
     @Override
     public void run() {
       if (!isActive()) {
-        delegate.onGuidsSinceFailed(new InactiveSessionException(null));
+        delegate.onGuidsSinceFailed(new InactiveSessionException());
         return;
       }
 
       Cursor cur;
       try {
         cur = dbHelper.getGUIDsSince(timestamp);
       } catch (Exception e) {
         delegate.onGuidsSinceFailed(e);
@@ -275,20 +275,20 @@ public abstract class AndroidBrowserRepo
                 Logger.debug(LOG_TAG, "Skipping filtered record " + r.guid);
               }
             }
             cursor.moveToNext();
           }
           delegate.onFetchCompleted(end);
         } catch (NoGuidForIdException e) {
           Logger.warn(LOG_TAG, "No GUID for ID.", e);
-          delegate.onFetchFailed(e, null);
+          delegate.onFetchFailed(e);
         } catch (Exception e) {
           Logger.warn(LOG_TAG, "Exception in fetchFromCursor.", e);
-          delegate.onFetchFailed(e, null);
+          delegate.onFetchFailed(e);
           return;
         }
       } finally {
         Logger.trace(LOG_TAG, "Closing cursor after fetch.");
         cursor.close();
       }
     }
   }
@@ -306,31 +306,31 @@ public abstract class AndroidBrowserRepo
       this.guids  = guids;
       this.end    = end;
       this.filter = filter;
     }
 
     @Override
     public void run() {
       if (!isActive()) {
-        delegate.onFetchFailed(new InactiveSessionException(null), null);
+        delegate.onFetchFailed(new InactiveSessionException());
         return;
       }
 
       if (guids == null || guids.length < 1) {
         Logger.error(LOG_TAG, "No guids sent to fetch");
-        delegate.onFetchFailed(new InvalidRequestException(null), null);
+        delegate.onFetchFailed(new InvalidRequestException());
         return;
       }
 
       try {
         Cursor cursor = dbHelper.fetch(guids);
         this.fetchFromCursor(cursor, filter, end);
       } catch (NullCursorException e) {
-        delegate.onFetchFailed(e, null);
+        delegate.onFetchFailed(e);
       }
     }
   }
 
   @Override
   public void fetchSince(long timestamp,
                          RepositorySessionFetchRecordsDelegate delegate) {
     if (this.storeTracker == null) {
@@ -355,25 +355,25 @@ public abstract class AndroidBrowserRepo
       this.since  = since;
       this.end    = end;
       this.filter = filter;
     }
 
     @Override
     public void run() {
       if (!isActive()) {
-        delegate.onFetchFailed(new InactiveSessionException(null), null);
+        delegate.onFetchFailed(new InactiveSessionException());
         return;
       }
 
       try {
         Cursor cursor = dbHelper.fetchSince(since);
         this.fetchFromCursor(cursor, filter, end);
       } catch (NullCursorException e) {
-        delegate.onFetchFailed(e, null);
+        delegate.onFetchFailed(e);
         return;
       }
     }
   }
 
   @Override
   public void fetchAll(RepositorySessionFetchRecordsDelegate delegate) {
     this.fetchSince(0, delegate);
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/FennecTabsRepository.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/FennecTabsRepository.java
@@ -163,17 +163,17 @@ public class FennecTabsRepository extend
               if (tabsRecord.lastModified >= timestamp ||
                   clientsDataDelegate.getLastModifiedTimestamp() >= timestamp) {
                 delegate.onFetchedRecord(tabsRecord);
               }
             } finally {
               cursor.close();
             }
           } catch (Exception e) {
-            delegate.onFetchFailed(e, null);
+            delegate.onFetchFailed(e);
             return;
           }
           delegate.onFetchCompleted(now());
         }
       };
 
       delegateQueue.execute(command);
     }
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/FormHistoryRepositorySession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/FormHistoryRepositorySession.java
@@ -122,17 +122,17 @@ public class FormHistoryRepositorySessio
   protected static final String[] GUID_COLUMNS = new String[] { FormHistory.GUID };
 
   @Override
   public void guidsSince(final long timestamp, final RepositorySessionGuidsSinceDelegate delegate) {
     Runnable command = new Runnable() {
       @Override
       public void run() {
         if (!isActive()) {
-          delegate.onGuidsSinceFailed(new InactiveSessionException(null));
+          delegate.onGuidsSinceFailed(new InactiveSessionException());
           return;
         }
 
         ArrayList<String> guids = new ArrayList<String>();
 
         final long sharedEnd = now();
         Cursor cur = null;
         try {
@@ -246,28 +246,28 @@ public class FormHistoryRepositorySessio
     }
 
     final RecordFilter filter = this.storeTracker.getFilter();
 
     Runnable command = new Runnable() {
       @Override
       public void run() {
         if (!isActive()) {
-          delegate.onFetchFailed(new InactiveSessionException(null), null);
+          delegate.onFetchFailed(new InactiveSessionException());
           return;
         }
 
         for (Callable<Cursor> cursorCallable : cursorCallables) {
           Cursor cursor = null;
           try {
             cursor = cursorCallable.call();
             fetchFromCursor(cursor, filter, delegate); // Closes cursor.
           } catch (Exception e) {
             Logger.warn(LOG_TAG, "Exception during fetchHelper", e);
-            delegate.onFetchFailed(e, null);
+            delegate.onFetchFailed(e);
             return;
           }
         }
 
         delegate.onFetchCompleted(end);
       }
     };
 
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/PasswordsRepositorySession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/android/PasswordsRepositorySession.java
@@ -73,17 +73,17 @@ public class PasswordsRepositorySession 
 
   @Override
   public void guidsSince(final long timestamp, final RepositorySessionGuidsSinceDelegate delegate) {
     final Runnable guidsSinceRunnable = new Runnable() {
       @Override
       public void run() {
 
         if (!isActive()) {
-          delegate.onGuidsSinceFailed(new InactiveSessionException(null));
+          delegate.onGuidsSinceFailed(new InactiveSessionException());
           return;
         }
 
         // Checks succeeded, now get GUIDs.
         final List<String> guids = new ArrayList<String>();
         try {
           Logger.debug(LOG_TAG, "Fetching guidsSince from data table.");
           final Cursor data = passwordsHelper.safeQuery(passwordsProvider, ".getGUIDsSince", GUID_COLS, dateModifiedWhere(timestamp), null, null);
@@ -126,17 +126,17 @@ public class PasswordsRepositorySession 
 
   @Override
   public void fetchSince(final long timestamp, final RepositorySessionFetchRecordsDelegate delegate) {
     final RecordFilter filter = this.storeTracker.getFilter();
     final Runnable fetchSinceRunnable = new Runnable() {
       @Override
       public void run() {
         if (!isActive()) {
-          delegate.onFetchFailed(new InactiveSessionException(null), null);
+          delegate.onFetchFailed(new InactiveSessionException());
           return;
         }
 
         final long end = now();
         try {
           // Fetch from data table.
           Cursor data = passwordsHelper.safeQuery(passwordsProvider, ".fetchSince",
                                                   getAllColumns(),
@@ -160,17 +160,17 @@ public class PasswordsRepositorySession 
             delegate.onFetchCompleted(end);
           } catch (Exception e) {
             Logger.error(LOG_TAG, "Delegate fetch completed callback failed.", e);
             // Don't call failure callback.
             return;
           }
         } catch (Exception e) {
           Logger.error(LOG_TAG, "Exception in fetch.");
-          delegate.onFetchFailed(e, null);
+          delegate.onFetchFailed(e);
         }
       }
     };
 
     delegateQueue.execute(fetchSinceRunnable);
   }
 
   @Override
@@ -188,17 +188,17 @@ public class PasswordsRepositorySession 
     }
 
     // Checks succeeded, now fetch.
     final RecordFilter filter = this.storeTracker.getFilter();
     final Runnable fetchRunnable = new Runnable() {
       @Override
       public void run() {
         if (!isActive()) {
-          delegate.onFetchFailed(new InactiveSessionException(null), null);
+          delegate.onFetchFailed(new InactiveSessionException());
           return;
         }
 
         final long end = now();
         final String where = RepoUtils.computeSQLInClause(guids.length, "guid");
         Logger.trace(LOG_TAG, "Fetch guids where: " + where);
 
         try {
@@ -217,17 +217,17 @@ public class PasswordsRepositorySession 
           if (!fetchAndCloseCursorDeleted(deleted, true, filter, delegate)) {
             return;
           }
 
           delegate.onFetchCompleted(end);
 
         } catch (Exception e) {
           Logger.error(LOG_TAG, "Exception in fetch.");
-          delegate.onFetchFailed(e, null);
+          delegate.onFetchFailed(e);
         }
       }
     };
 
     delegateQueue.execute(fetchRunnable);
   }
 
   @Override
@@ -399,17 +399,17 @@ public class PasswordsRepositorySession 
   @Override
   public void wipe(final RepositorySessionWipeDelegate delegate) {
     Logger.info(LOG_TAG, "Wiping " + BrowserContractHelpers.PASSWORDS_CONTENT_URI + ", " + BrowserContractHelpers.DELETED_PASSWORDS_CONTENT_URI);
 
     Runnable wipeRunnable = new Runnable() {
       @Override
       public void run() {
         if (!isActive()) {
-          delegate.onWipeFailed(new InactiveSessionException(null));
+          delegate.onWipeFailed(new InactiveSessionException());
           return;
         }
 
         // Wipe both data and deleted.
         try {
           context.getContentResolver().delete(BrowserContractHelpers.PASSWORDS_CONTENT_URI, null, null);
           context.getContentResolver().delete(BrowserContractHelpers.DELETED_PASSWORDS_CONTENT_URI, null, null);
         } catch (Exception e) {
@@ -554,17 +554,17 @@ public class PasswordsRepositorySession 
             delegate.onFetchedRecord(r);
           } else {
             Logger.debug(LOG_TAG, "Skipping filtered record " + r.guid);
           }
         }
       }
     } catch (Exception e) {
       Logger.error(LOG_TAG, "Exception in fetch.");
-      delegate.onFetchFailed(e, null);
+      delegate.onFetchFailed(e);
       return false;
     } finally {
       cursor.close();
     }
 
     return true;
   }
 
@@ -649,18 +649,16 @@ public class PasswordsRepositorySession 
     }
     storeDelegate.onRecordStoreSucceeded(record.guid);
   }
 
   /**
    * Make a PasswordRecord from a Cursor.
    * @param cur
    *        Cursor from query.
-   * @param deleted
-   *        true if creating a deleted Record, false if otherwise.
    * @return
    *        PasswordRecord populated from Cursor.
    */
   private static PasswordRecord passwordRecordFromCursor(Cursor cur) {
     if (cur.isAfterLast()) {
       return null;
     }
     String guid = RepoUtils.getStringFromCursor(cur, BrowserContract.Passwords.GUID);
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/delegates/DeferredRepositorySessionFetchRecordsDelegate.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/delegates/DeferredRepositorySessionFetchRecordsDelegate.java
@@ -22,21 +22,21 @@ public class DeferredRepositorySessionFe
       @Override
       public void run() {
          inner.onFetchedRecord(record);
       }
     });
   }
 
   @Override
-  public void onFetchFailed(final Exception ex, final Record record) {
+  public void onFetchFailed(final Exception ex) {
     executor.execute(new Runnable() {
       @Override
       public void run() {
-        inner.onFetchFailed(ex, record);
+        inner.onFetchFailed(ex);
       }
     });
   }
 
   @Override
   public void onFetchCompleted(final long fetchEnd) {
     executor.execute(new Runnable() {
       @Override
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/delegates/RepositorySessionFetchRecordsDelegate.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/delegates/RepositorySessionFetchRecordsDelegate.java
@@ -4,29 +4,29 @@
 
 package org.mozilla.gecko.sync.repositories.delegates;
 
 import java.util.concurrent.ExecutorService;
 
 import org.mozilla.gecko.sync.repositories.domain.Record;
 
 public interface RepositorySessionFetchRecordsDelegate {
-  public void onFetchFailed(Exception ex, Record record);
-  public void onFetchedRecord(Record record);
+  void onFetchFailed(Exception ex);
+  void onFetchedRecord(Record record);
 
   /**
    * Called when all records in this fetch have been returned.
    *
    * @param fetchEnd
    *        A millisecond-resolution timestamp indicating the *remote* timestamp
    *        at the end of the range of records. Usually this is the timestamp at
    *        which the request was received.
    *        E.g., the (normalized) value of the X-Weave-Timestamp header.
    */
-  public void onFetchCompleted(final long fetchEnd);
+  void onFetchCompleted(final long fetchEnd);
 
   /**
    * Called when a number of records have been returned but more are still expected to come,
    * possibly after a certain pause.
    */
   void onBatchCompleted();
 
   RepositorySessionFetchRecordsDelegate deferredFetchDelegate(ExecutorService executor);
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/downloaders/BatchingDownloader.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/downloaders/BatchingDownloader.java
@@ -136,30 +136,30 @@ public class BatchingDownloader {
         long batchLimit = repository.getDefaultBatchLimit();
         String sort = repository.getDefaultSort();
 
         try {
             SyncStorageCollectionRequest request = makeSyncStorageCollectionRequest(timestamp,
                     batchLimit, true, sort, null, offset);
             this.fetchWithParameters(timestamp, batchLimit, true, sort, null, request, fetchRecordsDelegate);
         } catch (URISyntaxException | UnsupportedEncodingException e) {
-            fetchRecordsDelegate.onFetchFailed(e, null);
+            fetchRecordsDelegate.onFetchFailed(e);
         }
     }
 
     public void fetch(String[] guids, RepositorySessionFetchRecordsDelegate fetchRecordsDelegate) {
         String ids = flattenIDs(guids);
         String index = "index";
 
         try {
             SyncStorageCollectionRequest request = makeSyncStorageCollectionRequest(
                     -1, -1, true, index, ids, null);
             this.fetchWithParameters(-1, -1, true, index, ids, request, fetchRecordsDelegate);
         } catch (URISyntaxException | UnsupportedEncodingException e) {
-            fetchRecordsDelegate.onFetchFailed(e, null);
+            fetchRecordsDelegate.onFetchFailed(e);
         }
     }
 
     public Server11Repository getServerRepository() {
         return this.repository;
     }
 
     public void onFetchCompleted(SyncStorageResponse response,
@@ -207,17 +207,17 @@ public class BatchingDownloader {
         try {
             newRequest = makeSyncStorageCollectionRequest(newer,
                     limit, full, sort, ids, offset);
         } catch (final URISyntaxException | UnsupportedEncodingException e) {
             this.workTracker.delayWorkItem(new Runnable() {
                 @Override
                 public void run() {
                     Logger.debug(LOG_TAG, "Delayed onFetchCompleted running.");
-                    fetchRecordsDelegate.onFetchFailed(e, null);
+                    fetchRecordsDelegate.onFetchFailed(e);
                 }
             });
             return;
         }
 
         if (offset != null && hasNotReachedLimit) {
             try {
                 this.fetchWithParameters(newer, limit, full, sort, ids, newRequest, fetchRecordsDelegate);
@@ -248,17 +248,17 @@ public class BatchingDownloader {
     public void onFetchFailed(final Exception ex,
                               final RepositorySessionFetchRecordsDelegate fetchRecordsDelegate,
                               final SyncStorageCollectionRequest request) {
         removeRequestFromPending(request);
         this.workTracker.delayWorkItem(new Runnable() {
             @Override
             public void run() {
                 Logger.debug(LOG_TAG, "Running onFetchFailed.");
-                fetchRecordsDelegate.onFetchFailed(ex, null);
+                fetchRecordsDelegate.onFetchFailed(ex);
             }
         });
     }
 
     public void onFetchedRecord(CryptoRecord record,
                                 RepositorySessionFetchRecordsDelegate fetchRecordsDelegate) {
         this.workTracker.incrementOutstanding();
         try {
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/synchronizer/RecordsChannel.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/synchronizer/RecordsChannel.java
@@ -189,18 +189,18 @@ public class RecordsChannel implements
       sink.store(record);
     } catch (NoStoreDelegateException e) {
       Logger.error(LOG_TAG, "Got NoStoreDelegateException in RecordsChannel.store(). This should not occur. Aborting.", e);
       delegate.onFlowStoreFailed(this, e, record.guid);
     }
   }
 
   @Override
-  public void onFetchFailed(Exception ex, Record record) {
-    Logger.warn(LOG_TAG, "onFetchFailed. Calling for immediate stop.", ex);
+  public void onFetchFailed(Exception ex) {
+    Logger.warn(LOG_TAG, "onFetchFailed. Informing sink, calling for immediate stop.", ex);
     numFetchFailed.incrementAndGet();
     this.consumer.halt();
     delegate.onFlowFetchFailed(this, ex);
   }
 
   @Override
   public void onFetchedRecord(Record record) {
     numFetched.incrementAndGet();
--- a/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/DefaultFetchDelegate.java
+++ b/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/DefaultFetchDelegate.java
@@ -22,17 +22,17 @@ import org.mozilla.gecko.sync.repositori
 
 public class DefaultFetchDelegate extends DefaultDelegate implements RepositorySessionFetchRecordsDelegate {
 
   private static final String LOG_TAG = "DefaultFetchDelegate";
   public ArrayList<Record> records = new ArrayList<Record>();
   public Set<String> ignore = new HashSet<String>();
 
   @Override
-  public void onFetchFailed(Exception ex, Record record) {
+  public void onFetchFailed(Exception ex) {
     performNotify("Fetch failed.", ex);
   }
 
   protected void onDone(ArrayList<Record> records, HashMap<String, Record> expected, long end) {
     Logger.debug(LOG_TAG, "onDone.");
     Logger.debug(LOG_TAG, "End timestamp is " + end);
     Logger.debug(LOG_TAG, "Expected is " + expected);
     Logger.debug(LOG_TAG, "Records is " + records);
--- a/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/ExpectInvalidRequestFetchDelegate.java
+++ b/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/ExpectInvalidRequestFetchDelegate.java
@@ -1,21 +1,20 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.gecko.background.sync.helpers;
 
 import org.mozilla.gecko.sync.repositories.InvalidRequestException;
-import org.mozilla.gecko.sync.repositories.domain.Record;
 
 public class ExpectInvalidRequestFetchDelegate extends DefaultFetchDelegate {
   public static final String LOG_TAG = "ExpInvRequestFetchDel";
 
   @Override
-  public void onFetchFailed(Exception ex, Record rec) {
+  public void onFetchFailed(Exception ex) {
     if (ex instanceof InvalidRequestException) {
       onDone();
     } else {
       performNotify("Expected InvalidRequestException but got ", ex);
     }
   }
 
   private void onDone() {
--- a/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessFetchDelegate.java
+++ b/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessFetchDelegate.java
@@ -1,22 +1,21 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.gecko.background.sync.helpers;
 
 import java.util.concurrent.ExecutorService;
 
 import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
-import org.mozilla.gecko.sync.repositories.domain.Record;
 
 public abstract class SimpleSuccessFetchDelegate extends DefaultDelegate implements
     RepositorySessionFetchRecordsDelegate {
   @Override
-  public void onFetchFailed(Exception ex, Record record) {
+  public void onFetchFailed(Exception ex) {
     performNotify("Fetch failed", ex);
   }
 
   @Override
   public RepositorySessionFetchRecordsDelegate deferredFetchDelegate(ExecutorService executor) {
     return this;
   }
 }
--- a/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/testhelpers/WBORepository.java
+++ b/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/testhelpers/WBORepository.java
@@ -154,17 +154,17 @@ public class WBORepository extends Repos
 
       trackRecord(toStore);
       storeDelegate.deferredStoreDelegate(delegateExecutor).onRecordStoreSucceeded(record.guid);
     }
 
     @Override
     public void wipe(final RepositorySessionWipeDelegate delegate) {
       if (!isActive()) {
-        delegate.onWipeFailed(new InactiveSessionException(null));
+        delegate.onWipeFailed(new InactiveSessionException());
         return;
       }
 
       Logger.info(LOG_TAG, "Wiping WBORepositorySession.");
       this.wbos = new ConcurrentHashMap<String, Record>();
 
       // Wipe immediately for the convenience of test code.
       wboRepository.wbos = new ConcurrentHashMap<String, Record>();
--- a/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/SynchronizerHelpers.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/SynchronizerHelpers.java
@@ -33,25 +33,25 @@ public class SynchronizerHelpers {
       delegate.deferredCreationDelegate().onSessionCreated(new WBORepositorySession(this) {
         @Override
         public void fetchSince(long timestamp,
                                final RepositorySessionFetchRecordsDelegate delegate) {
           super.fetchSince(timestamp, new RepositorySessionFetchRecordsDelegate() {
             @Override
             public void onFetchedRecord(Record record) {
               if (record.guid.contains(FAIL_SENTINEL)) {
-                delegate.onFetchFailed(new FetchFailedException(), record);
+                delegate.onFetchFailed(new FetchFailedException());
               } else {
                 delegate.onFetchedRecord(record);
               }
             }
 
             @Override
-            public void onFetchFailed(Exception ex, Record record) {
-              delegate.onFetchFailed(ex, record);
+            public void onFetchFailed(Exception ex) {
+              delegate.onFetchFailed(ex);
             }
 
             @Override
             public void onFetchCompleted(long fetchEnd) {
               delegate.onFetchCompleted(fetchEnd);
             }
 
             @Override
--- a/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/helpers/ExpectSuccessRepositorySessionFetchRecordsDelegate.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/helpers/ExpectSuccessRepositorySessionFetchRecordsDelegate.java
@@ -15,17 +15,17 @@ public class ExpectSuccessRepositorySess
     ExpectSuccessDelegate implements RepositorySessionFetchRecordsDelegate {
   public ArrayList<Record> fetchedRecords = new ArrayList<Record>();
 
   public ExpectSuccessRepositorySessionFetchRecordsDelegate(WaitHelper waitHelper) {
     super(waitHelper);
   }
 
   @Override
-  public void onFetchFailed(Exception ex, Record record) {
+  public void onFetchFailed(Exception ex) {
     log("Fetch failed.", ex);
     performNotify(new AssertionFailedError("onFetchFailed: fetch should not have failed."));
   }
 
   @Override
   public void onFetchedRecord(Record record) {
     fetchedRecords.add(record);
     log("Fetched record with guid '" + record.guid + "'.");
--- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/background/testhelpers/WBORepository.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/background/testhelpers/WBORepository.java
@@ -153,17 +153,17 @@ public class WBORepository extends Repos
 
       trackRecord(toStore);
       storeDelegate.deferredStoreDelegate(delegateExecutor).onRecordStoreSucceeded(record.guid);
     }
 
     @Override
     public void wipe(final RepositorySessionWipeDelegate delegate) {
       if (!isActive()) {
-        delegate.onWipeFailed(new InactiveSessionException(null));
+        delegate.onWipeFailed(new InactiveSessionException());
         return;
       }
 
       Logger.info(LOG_TAG, "Wiping WBORepositorySession.");
       this.wbos = new ConcurrentHashMap<String, Record>();
 
       // Wipe immediately for the convenience of test code.
       wboRepository.wbos = new ConcurrentHashMap<String, Record>();
--- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/downloaders/BatchingDownloaderTest.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/downloaders/BatchingDownloaderTest.java
@@ -52,20 +52,19 @@ public class BatchingDownloaderTest {
         public boolean isFailure;
         public boolean isFetched;
         public boolean isSuccess;
         public int batchesCompleted;
         public Exception ex;
         public Record record;
 
         @Override
-        public void onFetchFailed(Exception ex, Record record) {
+        public void onFetchFailed(Exception ex) {
             this.isFailure = true;
             this.ex = ex;
-            this.record = record;
         }
 
         @Override
         public void onFetchedRecord(Record record) {
             this.isFetched = true;
             this.record = record;
         }