Promise retries until success/failure with Typescript

Issue

My mobile app uploads several files to the server in succession, often from remote areas with questionable connection strength. For this reason, I want to make a few attempts to send the file. I also want to move on and attempt the next one in the event of a failure, with all error messages displayed at the end of the export (ie “10 files uploaded, 3 failed…”)

However, I’m having trouble figuring out the recursive retry pattern with promises. Here’s what I have so far:

sendFile(params, retries  3){
    console.log("SENDING FILE: ", retries, "attempts remaining", params)

    return new Promise((resolve, reject)>{
      if(retries > 0){
        this._sendFile(params)
        .then(()>{
          // Upload Success
          console.log("Upload Success!")
          resolve()
        })
        .catch((err)>{
          console.log("Upload Fail", err)
          // Retry
          this.sendFile(params, --retries)
        })
      }else{
        console.log("Failed 3 times!!!")
        //Record error
        this.exportStatus.errors.push({
          message:"A file failed to upload after 3 attempts.",
          params: params
        })

        //Resolve and move on to next export
        resolve()

      }
    })

  }

  _sendFile(params){

      // Mobile - File Transfer

        let options  {
          fileKey: "file_transfer",
          fileName: params.fileName,
          httpMethod: "PUT",
          chunkedMode: false,
          headers: {
            "x-user-email":this.settings.user.email,
            "x-user-token":this.settings.user.authentication_token,
          }
        }

        let fileTransfer  this.transfer.create()
        let url  encodeURI(this.settings.api_endpoint + params.url)

        return fileTransfer.upload(params.file, url, options, true)


  }

When I raise an exception on the server, I’ll see the “Failed 3 times!!!” error message, but the calling promise does not resolve for the rest of the export to move on. I believe this is because I’m created nested promises (ie creating a new promise with each retry). How can I have the original promise resolve after 3 retries?

Thanks!

Solution

Here’s what ended up working:

  sendFile(params, retries  3, promise  null){
    console.log("SENDING FILE: ", retries, "attempts remaining", params)

    if(retries > 0){
      return this._sendFile(params)
      .then(()>{
        // Upload Success
        console.log("Upload Success!")
        return Promise.resolve(true)
      })
      .catch((err)>{
        console.log("Upload Fail", err)

        this.exportStatus.retries++

        return this.sendFile(params, --retries) // <-- The important part
      })
    }else{
      console.log("Failed 3 times!!!")

      this.exportStatus.errors.push({
        message:"A file failed to upload after 3 attempts.",
        params: params
      })

      return Promise.resolve(false)

    }

  }

Answered By – mikewagz

Leave a Comment