text: import defaultValue from './defaultValue.js';
  import defined from './defined.js';
  import formatError from './formatError.js';
  
      /**
       * Provides details about an error that occurred in an {@link ImageryProvider} or a {@link TerrainProvider}.
       *
       * @alias TileProviderError
       * @constructor
       *
       * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that experienced the error.
       * @param {String} message A message describing the error.
       * @param {Number} [x] The X coordinate of the tile that experienced the error, or undefined if the error
       *        is not specific to a particular tile.
       * @param {Number} [y] The Y coordinate of the tile that experienced the error, or undefined if the error
       *        is not specific to a particular tile.
       * @param {Number} [level] The level of the tile that experienced the error, or undefined if the error
       *        is not specific to a particular tile.
       * @param {Number} [timesRetried=0] The number of times this operation has been retried.
       * @param {Error} [error] The error or exception that occurred, if any.
       */
      function TileProviderError(provider, message, x, y, level, timesRetried, error) {
          /**
           * The {@link ImageryProvider} or {@link TerrainProvider} that experienced the error.
           * @type {ImageryProvider|TerrainProvider}
           */
          this.provider = provider;
  
          /**
           * The message describing the error.
           * @type {String}
           */
          this.message = message;
  
          /**
           * The X coordinate of the tile that experienced the error.  If the error is not specific
           * to a particular tile, this property will be undefined.
           * @type {Number}
           */
          this.x = x;
  
          /**
           * The Y coordinate of the tile that experienced the error.  If the error is not specific
           * to a particular tile, this property will be undefined.
           * @type {Number}
           */
          this.y = y;
  
          /**
           * The level-of-detail of the tile that experienced the error.  If the error is not specific
           * to a particular tile, this property will be undefined.
           * @type {Number}
           */
          this.level = level;
  
          /**
           * The number of times this operation has been retried.
           * @type {Number}
           * @default 0
           */
          this.timesRetried = defaultValue(timesRetried, 0);
  
          /**
           * True if the failed operation should be retried; otherwise, false.  The imagery or terrain provider
           * will set the initial value of this property before raising the event, but any listeners
           * can change it.  The value after the last listener is invoked will be acted upon.
           * @type {Boolean}
           * @default false
           */
          this.retry = false;
  
          /**
           * The error or exception that occurred, if any.
           * @type {Error}
           */
          this.error = error;
      }
  
      /**
       * Handles an error in an {@link ImageryProvider} or {@link TerrainProvider} by raising an event if it has any listeners, or by
       * logging the error to the console if the event has no listeners.  This method also tracks the number
       * of times the operation has been retried and will automatically retry if requested to do so by the
       * event listeners.
       *
       * @param {TileProviderError} previousError The error instance returned by this function the last
       *        time it was called for this error, or undefined if this is the first time this error has
       *        occurred.
       * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that encountered the error.
       * @param {Event} event The event to raise to inform listeners of the error.
       * @param {String} message The message describing the error.
       * @param {Number} x The X coordinate of the tile that experienced the error, or undefined if the
       *        error is not specific to a particular tile.
       * @param {Number} y The Y coordinate of the tile that experienced the error, or undefined if the
       *        error is not specific to a particular tile.
       * @param {Number} level The level-of-detail of the tile that experienced the error, or undefined if the
       *        error is not specific to a particular tile.
       * @param {TileProviderError~RetryFunction} retryFunction The function to call to retry the operation.  If undefined, the
       *        operation will not be retried.
       * @param {Error} [errorDetails] The error or exception that occurred, if any.
       * @returns {TileProviderError} The error instance that was passed to the event listeners and that
       *          should be passed to this function the next time it is called for the same error in order
       *          to track retry counts.
       */
      TileProviderError.handleError = function(previousError, provider, event, message, x, y, level, retryFunction, errorDetails) {
          var error = previousError;
          if (!defined(previousError)) {
              error = new TileProviderError(provider, message, x, y, level, 0, errorDetails);
          } else {
              error.provider = provider;
              error.message = message;
              error.x = x;
              error.y = y;
              error.level = level;
              error.retry = false;
              error.error = errorDetails;
              ++error.timesRetried;
          }
  
          if (event.numberOfListeners > 0) {
              event.raiseEvent(error);
          } else {
              console.log('An error occurred in "' + provider.constructor.name + '": ' + formatError(message));
          }
  
          if (error.retry && defined(retryFunction)) {
              retryFunction();
          }
  
          return error;
      };
  
      /**
       * Handles success of an operation by resetting the retry count of a previous error, if any.  This way,
       * if the error occurs again in the future, the listeners will be informed that it has not yet been retried.
       *
       * @param {TileProviderError} previousError The previous error, or undefined if this operation has
       *        not previously resulted in an error.
       */
      TileProviderError.handleSuccess = function(previousError) {
          if (defined(previousError)) {
              previousError.timesRetried = -1;
          }
      };
  
      /**
       * A function that will be called to retry the operation.
       * @callback TileProviderError~RetryFunction
       */
  export default TileProviderError;
  