Example #1
0
            public void ReportsOfflineExceptionsToTheAnalyticsServiceAsANormalEvent()
            {
                var exception = new OfflineException();

                OrchestratorSyncComplete.OnNext(new Error(exception));

                AnalyticsService.OfflineModeDetected.Received().Track();
            }
Example #2
0
            public void DoNotReportOfflineExceptionsToTheAnalyticsService()
            {
                var exception = new OfflineException();

                OrchestratorSyncComplete.OnNext(new Error(exception));

                AnalyticsService.DidNotReceive().TrackSyncError(Arg.Any <Exception>());
            }
Example #3
0
        /// <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);
        }