Search code examples
javascripttypescriptionic-frameworkes6-promiseionic3

Promise retries until success/failure with Typescript


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)
    
        }
    
      }