如何通过错误处理在 post/put 请求中流式传输文件?

How to stream a file in post/put request with error handling?

这不是关于 "what is the best way to refactor the following code" 的问题。关于 "how can I refactor the following code to have any control over both of the exceptions".


我有以下代码在 PUT 请求中流式传输文件。

import fs from 'fs'
import got from 'got' // it doesn't really matters if it's `axious` or `got`

async function sendFile(addressToSend: string, filePath: string) {
      const body = fs.createReadStream(filePath)
      body.on('error', () => {
        console.log('we cached the error in block-1')
      })
      try {
        const result = await client.put(addressToSend, {
          body,
        })
      } catch (e) {
        console.log('we cached the error in block-2')
      }
}

我正在尝试以一种让我有机会在一个地方捕获所有错误的方式重构此代码。

上面的解决方案没有给我一个测试失败的方法stream。例如,如果我传递一个不存在的文件,该函数将同时打印 we cached the error in block-1we cached the error in block-2 但我没有办法重新抛出第一个错误或在测试中使用它无论如何。


注:

我不确定解决它的最佳方法是否是这样做:

因为当我传递一个不存在的文件路径时,rej 函数将被调用两次,这是非常糟糕的做法。

function sendFile(addressToSend: string, filePath: string) {
  return new Promise(async (res, rej) => {
    const body = fs.createReadStream(filePath)
    body.on('error', () => {
      console.log('we cached the error in block-1')
      rej('1')
    })
    try {
      const result = await client.put(addressToSend, {
        body,
      })
      res()
    } catch (e) {
      console.log('we cached the error in block-2')
      rej('2')
    }
  })
}

我不太喜欢它,但这是我能想到的最好的:

function streamFilePut(client: Got, url: string, filePath: string) {
  const body = fs.createReadStream(filePath)
  const streamErrorPromise = new Promise((_, rej) => body.on('error', rej))

  const resultPromise = new Promise((res, rej) => {
    return client
      .put(url, {
        body,
      })
      .then(res, rej)
  })

  return Promise.race([streamErrorPromise, resultPromise])
}