/// <summary> /// Tests that throwing an exception of type toThrow from the http handler causes the push sync to be aborted /// </summary> /// <param name="toThrow">The exception to simulate coming from http layer</param> /// <param name="expectedStatus">The expected status of push operation as reported in PushCompletionResult and PushFailedException</param> /// <returns></returns> private async Task TestPushAbort(Exception toThrow, MobileServicePushStatus expectedStatus) { bool thrown = false; var hijack = new TestHttpHandler(); hijack.OnSendingRequest = req => { if (!thrown) { thrown = true; throw toThrow; } return Task.FromResult(req); }; var operationHandler = new MobileServiceSyncHandlerMock(); hijack.SetResponseContent("{\"id\":\"abc\",\"String\":\"Hey\"}"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); await service.SyncContext.InitializeAsync(new MobileServiceLocalStoreMock(), operationHandler); IMobileServiceSyncTable<StringIdType> table = service.GetSyncTable<StringIdType>(); var item = new StringIdType() { Id = "an id", String = "what?" }; await table.InsertAsync(item); Assert.AreEqual(service.SyncContext.PendingOperations, 1L); MobileServicePushFailedException ex = await ThrowsAsync<MobileServicePushFailedException>(service.SyncContext.PushAsync); Assert.AreEqual(ex.PushResult.Status, expectedStatus); Assert.AreEqual(ex.PushResult.Errors.Count(), 0); Assert.AreEqual(operationHandler.PushCompletionResult.Status, expectedStatus); // the insert operation is still in queue Assert.AreEqual(service.SyncContext.PendingOperations, 1L); await service.SyncContext.PushAsync(); Assert.AreEqual(service.SyncContext.PendingOperations, 0L); Assert.AreEqual(operationHandler.PushCompletionResult.Status, MobileServicePushStatus.Complete); }
private async Task FinalizePush(OperationBatch batch, MobileServicePushStatus batchStatus, IEnumerable<MobileServiceTableOperationError> syncErrors) { var result = new MobileServicePushCompletionResult(syncErrors, batchStatus); try { await batch.SyncHandler.OnPushCompleteAsync(result); // now that we've successfully given the errors to user, we can delete them from store await batch.DeleteErrorsAsync(); } catch (Exception ex) { batch.OtherErrors.Add(ex); } if (batchStatus != MobileServicePushStatus.Complete || batch.HasErrors(syncErrors)) { List<MobileServiceTableOperationError> unhandledSyncErrors = syncErrors.Where(e => !e.Handled).ToList(); Exception inner; if (batch.OtherErrors.Count == 1) { inner = batch.OtherErrors[0]; } else { inner = batch.OtherErrors.Any() ? new AggregateException(batch.OtherErrors) : null; } // create a new result with only unhandled errors result = new MobileServicePushCompletionResult(unhandledSyncErrors, batchStatus); this.TaskSource.TrySetException(new MobileServicePushFailedException(result, inner)); } else { this.TaskSource.SetResult(0); } }
/// <summary> /// Initializes a new instance of <see cref="MobileServicePushCompletionResult"/> /// </summary> /// <param name="errors">Collection of errors that occured on executing operation on remote table.</param> /// <param name="status">The state in which push completed.</param> public MobileServicePushCompletionResult(IEnumerable<MobileServiceTableOperationError> errors, MobileServicePushStatus status) { this.Errors = new ReadOnlyCollection<MobileServiceTableOperationError>(errors as IList<MobileServiceTableOperationError> ?? new List<MobileServiceTableOperationError>(errors)); this.Status = status; }
/// <summary> /// Changes the status of the operation batch to aborted with the specified reason. /// </summary> /// <param name="reason">Status value that respresents the reason of abort.</param> public void Abort(MobileServicePushStatus reason) { Debug.Assert(reason != MobileServicePushStatus.Complete); this.AbortReason = reason; }
/// <summary> /// Initializes a new instance of <see cref="MobileServicePushCompletionResult"/> /// </summary> /// <param name="errors">Collection of errors that occured on executing operation on remote table.</param> /// <param name="status">The state in which push completed.</param> public MobileServicePushCompletionResult(IEnumerable <MobileServiceTableOperationError> errors, MobileServicePushStatus status) { this.Errors = new ReadOnlyCollection <MobileServiceTableOperationError>(errors as IList <MobileServiceTableOperationError> ?? new List <MobileServiceTableOperationError>(errors)); this.Status = status; }