my Flawed Retry Function

A flawed retry function in simulated usage example

by Jeremy Armstrong

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<div ng-app="myModule">
  <div ng-controller="MyController">
    <span>result is:</span><br>
    {{ result }}
  </div>
</div>

JavaScript

/*
 	numFailures {number}
	- How many failures to simulate. I.E. How many retries are necisary to get a
  	successful result from the "server."

	retryAttempts {number}
	- How many retries will be attempted before retry() should give up.
  
  If numFailures is 0 retry() will never trigger a retry.
	
	If numFailures is higher than retryAttempts retry() should eventually reject
  with the error message of the last failed "connection" attempt.
*/

// Intended usage, ideal circumstances.
// Works.
//var numFailures = 0, retryAttempts = 6;

// Intended usage, unrealiable communication.
// Incorrect result.
var numFailures = 2, retryAttempts = 6;

// Intended usage, service outage.
// Incorrect result. Even the error at the end fails.
//var numFailures = 7, retryAttempts = 6;

// Abnormal usage, to demonstrate functioning retry failure.
// Works.
//var numFailures = 1, retryAttempts = 0;

angular
  .module('myModule', []);



angular
  .module('myModule')
  .factory('MyFactory', function($q, $timeout) {



		/**
     * Angularjs $resource aware retry for remote method calls. Calls
     * itself recursively on each failure up to 'retries' times using
     * exponential backoff starting at 100+(1-50)ms.
     * 
     * @arg {number} retries Number of retries to attempt before failing
     * @arg {function} func The function (passed as an annonomous
     *  function or a reference to a function object) to retry on
     *  failure. Must return a Resource object a la the AngularJS
     *  $resource library.
     * @arg {number} i (optional) Used internally to keep track of the
     *  current iteration count.
     * 
     * @return {promise} will return a new promise which resolves when
     *  the resource promise resolves or rejects after all retries have
     *  failed.
     **/
    function retry(retries, func, i) {
      /*** my flawed retry function ***/
      i = i || 1;

      // get resource from func() (likely remote server)
      var resource = func(i); //...