andrewrk / node-s3-client

high level amazon s3 client for node.js
MIT License
1k stars 303 forks source link

Return of the callback twice error #198

Open freethejazz opened 6 years ago

freethejazz commented 6 years ago

When uploading a file, I am intermittently, but fairly regularly (1/3) getting the following error:

Error: callback called twice
    at onCb (/node_modules/pend/index.js:36:23)
    at Response.<anonymous> (/node_modules/s3/lib/index.js:401:9)
    at Request.<anonymous> (/node_modules/aws-sdk/lib/request.js:364:18)
    at Request.callListeners (/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    at Request.emit (/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/node_modules/aws-sdk/lib/state_machine.js:14:12)

This was an issue in 2014 as well, but Amazon fixed their library. It appears that this issue has cropped up again: https://github.com/aws/aws-sdk-js/issues/1617

Maybe it's time to revive the wtfAmazon workaround again? Here's where it was implemented: https://github.com/andrewrk/node-s3-client/commit/3f26bc119530c74e14850558ecbc556c2474fa64 And subsequently removed when it was fixed in the dependency: https://github.com/andrewrk/node-s3-client/commit/b6d76af9cdcca0ac1d85d3c00391f63dd07f9392

It should be noted that I'm manually passing in an s3Client per the workaround instructions in https://github.com/andrewrk/node-s3-client/issues/175

ghost commented 5 years ago

Same. My entire setup is shown below.

I wonder if the uploader.on('end') handler gets called even if there's an error? It's not easy to test, so I might wrap the end handler to check if error already happened...(and vice versa). I'll report the results of that change here if I can remember to.

/** s3-client client created from existing AWS.S3 object.
 * See https://github.com/matrus2/node-s3-client#readme
 */
const s3Client = s3.createClient({
  s3Client: storage,
  maxAsyncS3: MAX_ASYNC,
  s3RetryCount: RETRY_COUNT,
  s3RetryDelay: RETRY_DELAY,
  multipartUploadThreshold: MULTIPART_UPLOADS_MINSIZE,
  multipartUploadSize: MULTIPART_UPLOADS_PARTSIZE,
});

/** @param {AWS.S3.PutObjectRequest} params AWS.S3 putObject params except for
 * `Body` and `ContentLength`. */
function saveFile(srcPath, params) {
  const {
    Body: bodyFromParams,
    ContentLength: contentLengthFromParams,
  } = params;
  if (bodyFromParams || contentLengthFromParams) {
    throw new Error(`saveFile params not allowed: Body, ContentLength.`);
  }
  return new Promise((resolve, reject) => {
    const uploader = s3Client.uploadFile({
      localFile: srcPath,
      s3Params: params,
    });
    uploader.on('error', reject);
    uploader.on('end', resolve);
  });
}
Error: callback called twice
    at onCb (/editor/node_modules/pend/index.js:36:23)
    at Response.<anonymous> (/editor/node_modules/s3-client/lib/index.js:406:9)
    at Request.<anonymous> (/editor/node_modules/aws-sdk/lib/request.js:364:18)
    at Request.callListeners (/editor/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/editor/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/editor/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/editor/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/editor/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /editor/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/editor/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/editor/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/editor/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
    at Request.emit (/editor/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/editor/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/editor/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/editor/node_modules/aws-sdk/lib/state_machine.js:14:12)