json http请求的承诺中的.catch子句的未接收错误

发布于 2025-01-25 09:19:10 字数 2356 浏览 2 评论 0原文

我有此功能从API端点收集JSON数据:

  export const getDataAPI = (token_id) => {
  const url = `https://api.url.com/tokens/` + token_id;
  const options = {method: 'GET', headers: {Accept: 'application/json'}};
  const request = fetch(url, options)
    .then(response => { if (response.status === 200) {
        return response.json();
      } else if ([404, 429, 500].includes(response.status)) {
        return response.status;
      } else {
        return response.json()
          .then(json => {
            console.log("Error: getDataAPI response status", response.status);
            throw json;
          })
      }
    })
    .catch(error => { throw error; });
  return Promise.resolve(request);
};

我已经通过此功能收集了超过130万的记录。我想遇到任何意外的问题,以便我可以优雅地暂停几秒钟,然后重试。但是我遇到了2个错误,这些错误未发送到.CATCH子句。即使响应< / code>为空 / null / undefined,我也希望至少看到console.log的输出> 这些错误只发生一次。

undefined:1

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at Response.json (file:///home/user/node_modules/node-fetch/src/body.js:149:15)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async file:///home/user/path/to/file.mjs:94:20
file:///home/user/node_modules/node-fetch/src/index.js:108
            reject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error));
                   ^

FetchError: request to https://api.url.com/tokens/29727608 failed, reason: read ECONNRESET
    at ClientRequest.<anonymous> (file:///home/user/node_modules/node-fetch/src/index.js:108:11)
    at ClientRequest.emit (node:events:526:28)
    at TLSSocket.socketErrorListener (node:_http_client:442:9)
    at TLSSocket.emit (node:events:526:28)
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  type: 'system',
  errno: 'ECONNRESET',
  code: 'ECONNRESET',
  erroredSysCall: 'read'
}
  1. 我不明白为什么这些错误不会被该功能捕获。有人可以解释一下吗?

  2. 如何修复该功能,以便捕获此类错误?

  3. 我应该寻找什么输出来识别这些错误,syntaxerrorfetcherror?是否有一个变量可以监视错误代码?

I have this function that collects JSON data from an API endpoint:

  export const getDataAPI = (token_id) => {
  const url = `https://api.url.com/tokens/` + token_id;
  const options = {method: 'GET', headers: {Accept: 'application/json'}};
  const request = fetch(url, options)
    .then(response => { if (response.status === 200) {
        return response.json();
      } else if ([404, 429, 500].includes(response.status)) {
        return response.status;
      } else {
        return response.json()
          .then(json => {
            console.log("Error: getDataAPI response status", response.status);
            throw json;
          })
      }
    })
    .catch(error => { throw error; });
  return Promise.resolve(request);
};

I have collected over 1.3M records with this function. I would like to catch any unexpected problems so I can gracefully pause for a few seconds and try again. But I came across 2 errors that were not sent to the .catch clause. Even if response is empty / null / undefined, I would expect at least to see the output of console.log("Error: getDataAPI response status", response.status);
These errors only happened once each.

undefined:1

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at Response.json (file:///home/user/node_modules/node-fetch/src/body.js:149:15)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async file:///home/user/path/to/file.mjs:94:20
file:///home/user/node_modules/node-fetch/src/index.js:108
            reject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error));
                   ^

FetchError: request to https://api.url.com/tokens/29727608 failed, reason: read ECONNRESET
    at ClientRequest.<anonymous> (file:///home/user/node_modules/node-fetch/src/index.js:108:11)
    at ClientRequest.emit (node:events:526:28)
    at TLSSocket.socketErrorListener (node:_http_client:442:9)
    at TLSSocket.emit (node:events:526:28)
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  type: 'system',
  errno: 'ECONNRESET',
  code: 'ECONNRESET',
  erroredSysCall: 'read'
}
  1. I don't understand why these errors were not caught by the function. Can someone please explain this?

  2. How can I fix the function so it also catches this sort of errors?

  3. What is the output I should be looking for to identify these errors, SyntaxError and FetchError? Is there a variable to monitor for error codes for example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稚然 2025-02-01 09:19:10

我希望至少会看到console.log的输出(“错误:getDataapi响应状态”,Response.status);

该代码不在捕获子句中,它在然后在子句中。

return response.json()
          .then(json => {
            console.log("Error: getDataAPI response status", response.status);
            throw json;
          })

您的catch简直就是复发:

.catch(error => { throw error; });

这将给您带来未知的错误。

您需要记录/处理捕获量中的错误,而不是然后子句:

 export const getDataAPI = (token_id) => {
  const url = `https://api.url.com/tokens/` + token_id;
  const options = {method: 'GET', headers: {Accept: 'application/json'}};
  const request = fetch(url, options)
    .then(response => { if (response.status === 200) {
        return response.json();
      } else if ([404, 429, 500].includes(response.status)) {
        return response.status;
      } else {
        console.log("Error: getDataAPI response status", response.status);
        // you can swallow the error here if you want, or try to parse it anyway
        return response.json()
      }
    })
    .catch(error => { 
       console.log('Handling error', error);
       throw error;
    });

  // wrapping the request in a Promise.resolve is also unnecessary 
  // return Promise.resolve(request);
  return request;
};
 

I would expect at least to see the output of console.log("Error: getDataAPI response status", response.status);

That code isn't in a catch clause, it's in a then clause.

return response.json()
          .then(json => {
            console.log("Error: getDataAPI response status", response.status);
            throw json;
          })

Your catch is simply rethrowing:

.catch(error => { throw error; });

Which will give you an uncaught error.

You need to log/handle the error in the catch, not the then clause:

 export const getDataAPI = (token_id) => {
  const url = `https://api.url.com/tokens/` + token_id;
  const options = {method: 'GET', headers: {Accept: 'application/json'}};
  const request = fetch(url, options)
    .then(response => { if (response.status === 200) {
        return response.json();
      } else if ([404, 429, 500].includes(response.status)) {
        return response.status;
      } else {
        console.log("Error: getDataAPI response status", response.status);
        // you can swallow the error here if you want, or try to parse it anyway
        return response.json()
      }
    })
    .catch(error => { 
       console.log('Handling error', error);
       throw error;
    });

  // wrapping the request in a Promise.resolve is also unnecessary 
  // return Promise.resolve(request);
  return request;
};
 
一刻暧昧 2025-02-01 09:19:10

在Xdumaine的帮助下,我能够弄清楚自己在做什么错。

  1. 这些错误没有触发console.log报告,因为它们甚至在可以组成JSON字符串之前就提出了。

  2. 该功能正在捕获错误,只有对它们没有任何做法。我发现并测试。作为演示,这是一种创建错误并确认.catch()子句处理的方法:


export const getDataAPI = (token_id) => {
  const url = `https://api.url.com/tokens/` + token_id;
  const options = {method: 'GET', headers: {Accept: 'application/json'}};
  const request = fetch(url, options)
    .then(response => { 
        throw new SyntaxError('Hello', 'someFile.js', 10);
        if (response.status === 200) {
        return response.json();
      } else if ([404, 429, 500].includes(response.status)) {
        return response.status;
      } else {
        return response.json()
          .then(json => {
            console.log("Error: getDataAPI response status", response.status);
            throw json;
          })
      }
    })
    .catch(error => { 
      console.log('Caught error', error.name);
      throw error; 
      });
  return request;
};
  1. 如上所述的页面所示,error.name.name包含错误的名称。

With xdumaine's help I was able to figure out what I was doing wrong.

  1. The errors were not triggering the console.log reporting because they were raised even before a JSON string could be composed.

  2. The function was catching the errors, only there was nothing being done to them. I found this page useful to better understand and test this. As a demonstration, here is a way to create an error and confirm the .catch() clause is handling it:

export const getDataAPI = (token_id) => {
  const url = `https://api.url.com/tokens/` + token_id;
  const options = {method: 'GET', headers: {Accept: 'application/json'}};
  const request = fetch(url, options)
    .then(response => { 
        throw new SyntaxError('Hello', 'someFile.js', 10);
        if (response.status === 200) {
        return response.json();
      } else if ([404, 429, 500].includes(response.status)) {
        return response.status;
      } else {
        return response.json()
          .then(json => {
            console.log("Error: getDataAPI response status", response.status);
            throw json;
          })
      }
    })
    .catch(error => { 
      console.log('Caught error', error.name);
      throw error; 
      });
  return request;
};
  1. As demonstrated in the page linked above, error.name contains the name of the error.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文