public void ReportsOfflineExceptionsToTheAnalyticsServiceAsANormalEvent() { var exception = new OfflineException(); OrchestratorSyncComplete.OnNext(new Error(exception)); AnalyticsService.OfflineModeDetected.Received().Track(); }
public void DoNotReportOfflineExceptionsToTheAnalyticsService() { var exception = new OfflineException(); OrchestratorSyncComplete.OnNext(new Error(exception)); AnalyticsService.DidNotReceive().TrackSyncError(Arg.Any <Exception>()); }
/// <summary> /// Execute via HTTP async. /// </summary> /// <param name="method">The HTTP method.</param> /// <param name="uri">The full uri.</param> /// <param name="parameters">The query parameters.</param> /// <typeparam name="T">The class type.</typeparam> /// <returns>The <see cref="Task{BaseEnvelope{T}}"/>.</returns> protected async Task <IBaseEnvelope <T> > ExecuteAsync <T>( HttpMethod method, string uri, object parameters) where T : class { const int Retry = 5; var tryAgain = true; var counter = 0; var response = default(HttpResponseMessage); var result = default(IBaseEnvelope <T>); try { // Create the HTTP Request object based on HttpClient PCL var request = new HttpRequestObject(this.Serializer); var defaultDelay = TimeSpan.FromSeconds(10); while (tryAgain && counter++ < Retry) { var delay = defaultDelay; // Send the HttpRequest asynchronously response = await request.ExecuteRequestAsync <T>( this.client, method, this.Endpoint, uri, parameters); // Check if response was a success // i.e. HTTP 200 OK // TODO: Need refactor, this flag may not belong here tryAgain = !response.IsSuccessStatusCode; if (tryAgain) { switch ((int)response.StatusCode) { case 401: // 401 Unauthorised Exception. // Immediately retry on first and second request. // If auth is required, sometimes two request are // required, first one to determine which scheme // are being used. // Reference: // http://stackoverflow.com/a/17025435/1615437 delay = counter <= 1 ? TimeSpan.FromMilliseconds(1) : defaultDelay; break; case 429: // 429 Too Many Requests. // Log the exception if the API rate limit // has been exceeded. // Reference: // https://developer.yammer.com/restapi/#rest-ratelimits // TODO: Create specified delay based on docs Debug.WriteLine("Rate Limit Exceeded"); // Wait 10 seconds before trying again delay = defaultDelay; break; } // Retry request with a specified delay await TaskEx.Delay(delay); } } if (!tryAgain) { var responseHandler = new HttpResponseHandler( this.Deserializer, this.ResponseErrorHandler); result = await responseHandler.HandleResponseAsync <T>(response); response.Dispose(); } } catch (AggregateException ae) { // Catch Yammer aggregate exception ae.Flatten().Handle(e => { // Return all exception other than Rate Limit Exceeded type if (e.GetType() != typeof(RateLimitExceededException)) { result = new BaseEnvelope <T> { Exception = e.InnerException ?? e }; } return(true); }); } catch (HttpRequestException httpEx) { // Catch other HTTP exception if (httpEx.InnerException is WebException) { var webEx = httpEx.InnerException as WebException; var status = webEx.Status; if (status.ToString() == "NameResolutionFailure") { var offlineException = new OfflineException(); result = new BaseEnvelope <T> { Exception = offlineException }; } } } catch (Exception ex) { result = new BaseEnvelope <T> { Exception = ex }; } return(result); }