在云功能中使用 HTTP 请求时读取 ECONNRESET 错误

read ECONNRESET error when working with HTTP request in cloud function

我正在尝试向 Firebase 云函数中的 App Store verifyReceipt 端点发送 post 请求。但是,我在云函数日志中收到以下错误:

{ Error: read ECONNRESET
    at TLSWrap.onread (net.js:622:25)
  errno: 'ECONNRESET',
  code: 'ECONNRESET',
  syscall: 'read',

不过,这个错误只是偶尔发生。它不会每次都发生,所以该功能显然有效,但有时会出现问题,我不确定是什么。

与此相关的大多数其他解决方案都是由于承诺错误造成的,但我认为这不是问题所在。下面是完整的函数:

exports.handleSubscriptionIAP_IOS_S2S = functions.https.onRequest((req, res) => {
    let data = req.body;

    console.log('received ios s2s notification with body:', data);

    let base64String = data.unified_receipt.latest_receipt;

    let boolStatus = true;
    // The user has changed the auto renewal status, store the change
    if(data.notification_type === 'DID_CHANGE_RENEWAL_STATUS') {
        boolStatus = (data.auto_renew_status === 'true');
    }

    console.log(data.notification_type);

    if(base64String) {
        var options = {
            method: 'post',
            url: 'https://buy.itunes.apple.com/verifyReceipt',
            data: ({
                "receipt-data" : base64String,
                "password" : "***",
                "exclude-old-transactions" : true
            })
        };

        var optionsSandbox = {
            method: 'post',
            url: 'https://sandbox.itunes.apple.com/verifyReceipt',
            data: ({
                "receipt-data" : base64String,
                "password" : "***",
                "exclude-old-transactions" : true
            })
        };

        return axios(options)
        .then((response) => {
            if(response.data.status === 21007) {
                return 'handle_sandbox';
            }

            // Got valid response from Apple, pass down chain
            else {
                return response;
            }
        })
        .then((response) => {
            // Send post request to sandbox endpoint
            if(response === 'handle_sandbox') {
                return axios(optionsSandbox);
            }

            // Pass response down chain
            else {
                return response;
            }
        })
        .then((response) => {
            // Handle response from Apple verifyReceipt endpoint here
            // Both production and sandbox will end up here
            // See here for values in response.data: https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info

            console.log('received ios s2s notification verify receipt response with body:', response.data);
            // Status 0 means request is valid
            if(response.data.status === 0) {
                // Get receipt info of latest receipt
                // Only one object in array is return since we exclude old transactions
                let latestReceipt = response.data.latest_receipt_info[0];

                // Save receipt into Firestore
                return db.collection('appStoreReceipts').doc(latestReceipt.original_transaction_id).set({
                    latest_receipt_info: latestReceipt,

                    expiresTimestamp: admin.firestore.Timestamp.fromMillis(parseInt(latestReceipt.expires_date_ms)),
                    originalTransactionID: latestReceipt.original_transaction_id,

                    autoRenewStatus: boolStatus,

                    base64Receipt: response.data.latest_receipt,
                }, { merge: true });
            }
            else {
                return null;
            }
        })
        .then((result) => {
            if(result) {
                return res.status(200).end();
            }
            else {
                return res.status(400).end();
            }
        })
        .catch((error) => {
            console.log('an error occured handling the subscription', error);

            return res.status(400).end();
        })
    }
    else {
        console.log('invalid receipt', data);

        return res.status(400).end();
    }
});

感谢您提供的任何帮助!

ECONNRESET只是表示连接的另一端关闭了它。这可能意味着很多事情。这可能不是你的代码的错,除非你在这个请求中做了非常糟糕的事情,Apple 决定关闭连接。如果您认为他们的做法不正确,您应该直接联系他们的支持人员。