【问题标题】:Error: Socket hang up inside google cloud (nodejs) function错误:谷歌云(nodejs)函数内的套接字挂起
【发布时间】:2021-07-29 04:04:34
【问题描述】:

我正在使用谷歌云功能从 Firestore 获取令牌,检查它是否仍然处于活动状态,如果是则返回访问令牌。其他:

  1. 从 secretmanager 获取刷新令牌
  2. 刷新
  3. 在 Secret Manager 中更新刷新令牌
  4. 在 Firebase 中更新访问令牌

现在我有时会收到此错误...此函数至少每 15 分钟从不同的云函数调用一次。错误每天发生 5 次。我看过this 的帖子,但无法将其转换为我的代码。

错误:

FetchError: request to https://europe-west1-project.cloudfunctions.net/getToken failed, reason: socket hang up
        at ClientRequest.<anonymous> (/workspace/node_modules/node-fetch/lib/index.js:1461:11)
        at ClientRequest.emit (events.js:315:20)
        at ClientRequest.EventEmitter.emit (domain.js:467:12)
        at TLSSocket.socketOnEnd (_http_client.js:493:9)
        at TLSSocket.emit (events.js:327:22)
        at TLSSocket.EventEmitter.emit (domain.js:529:15)
        at endReadableNT (internal/streams/readable.js:1327:12)
        at processTicksAndRejections (internal/process/task_queues.js:80:21) 

代码:

const { SecretManagerServiceClient } = require("@google-cloud/secret-manager");
const client = new SecretManagerServiceClient();
const name = `projects/${process.env["PROJECT"]}/secrets/TOKEN/versions/latest`;

const axios = require("axios");
const milliseconds = new Date().getTime()
const now = Math.round(milliseconds / 1000);

const { Firestore } = require("@google-cloud/firestore");
const firestore = new Firestore();
const tokens = firestore.collection("tokens");

module.exports = async function getToken() {
  let responseData;

  await tokens.where("system", "==", "x").limit(1).get()
    .then((res) => {
      res.forEach((snap) => {
        responseData = snap.data();
      });
    })
    .catch((err) => {
      console.error(JSON.stringify(err));
    });
  
  console.log(`custom_log: now = ${now}`)
  console.log(JSON.stringify(responseData))
  
  if (now - responseData.timestamp < 250) {
    console.log(`custom_log: Returning access token from Firebase`)
    return responseData.access_token;
  } else {
    console.log(`custom_log: Return new access token`)
    return await refreshToken();
  }
};

async function refreshToken() {
  const [version] = await client.accessSecretVersion({ name: name });
  const secret = version.payload.data.toString();

  const config = {
    method: "post",
    url: "https://login.webpage.com/token?grant_type=client_credentials",
    headers: {
      Authorization: `Basic ${secret}`,
    },
  };
  return axios(config)
    .then((response) => {
      updateAccesToken(response.data.access_token)
      return response.data.access_token;
    })
    .catch((error) => {
      console.error(`custom_error: Error refresh token: ${error.message}`);
    });
}

async function updateAccesToken(token) {
  await tokens.doc('token').update({
    timestamp: now,
    access_token: token,
    dateTime: new Date(milliseconds).toISOString()
  })
  console.log('custom_log: access_token updated in Firestore')
}

【问题讨论】:

  • 对于 HTTP 触发的云函数 require the response to be sent,否则您应该确保返回正确的 Promise 以终止函数,您的 return responseData.access_token; 是否被正确调用? (这似乎不是一个有效的承诺)。我无法调试它,因为您对多个服务的多次调用可能会失败并返回错误的响应,我建议重构您的代码以返回正确的值(预计会有 Promise,而不仅仅是将其记录到控制台)

标签: node.js google-cloud-firestore google-cloud-functions


【解决方案1】:

2021/09/13 更新,即使我做了一个新的云功能没有设置超时(使用相同的代码),错误不再发生;为了以防万一,我将 google-auth-library 从 6.1.6 更新到 7.9.1,到目前为止它可以正常工作

2021/09/10 更新,为了测试我的程序需要多少时间,我将超时时间改回 60 秒,但它仍然有效...现在正在寻找重现的方法 p>

原始信息: 我在云功能上遇到了同样的错误(它在本地环境中工作)。

我将云功能的超时设置为80秒后,错误似乎解决了。

这些是我的程序执行的步骤,仅供参考

  1. 从 Secret Manager 获取数据
  2. 使用 google-api 读取 2 个电子表格
  3. 使用 google-api 更新 1 个电子表格

使用以前的版本(从 secret-manager 获取数据,然后读取 1 个电子表格并更新它),不会发生此错误。

【讨论】:

    猜你喜欢
    • 2015-09-13
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    相关资源
    最近更新 更多