Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

報告錯誤

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

自動報錯

您可以從 Cloud Functions 向Error Reporting發出錯誤,如下所示:

節點.js

// These WILL be reported to Error Reporting
throw new Error('I failed you'); // Will cause a cold start if not caught

// These WILL be reported to Error Reporting
console.error(new Error('I failed you')); // Logging an Error object
console.error('I failed you'); // Logging something other than an Error object
throw 1; // Throwing something other than an Error object
callback('I failed you');
res.status(500).send('I failed you');

如果您想要更細粒度的錯誤報告,您可以使用錯誤報告客戶端庫

您可以在 GCP Console 的錯誤報告中查看報告的錯誤。當您從 GCP Console的函數列表中選擇特定函數時,您還可以看到該函數報告的錯誤。

您的函數產生的未捕獲異常將出現在錯誤報告中。請注意,某些類型的未捕獲異常(例如那些異步拋出的異常)將導致在未來的函數調用時發生冷啟動。這會增加您的函數運行所需的時間。

手動報錯

要從函數向Error Reporting 報告錯誤,請使用Cloud Logging API。

導入依賴項

在您的functions目錄中,安裝適用於 Node.js 的 Cloud Logging 客戶端庫:

npm install --save @google-cloud/logging

導入並初始化 Cloud Logging 客戶端庫:

const Logging = require('@google-cloud/logging');

// Instantiates a client
const logging = Logging();

發送到雲日誌

格式正確的日誌條目需要一個MonitoredResource對象和一個ErrorEvent對象。

此示例reportError函數演示了向 Error Reporting 報告錯誤所需的最少數據。

function reportError(err, context = {}) {
  // This is the name of the log stream that will receive the log
  // entry. This name can be any valid log stream name, but must contain "err"
  // in order for the error to be picked up by Error Reporting.
  const logName = 'errors';
  const log = logging.log(logName);

  // https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
  const metadata = {
    resource: {
      type: 'cloud_function',
      labels: { function_name: process.env.FUNCTION_NAME },
    },
  };

  // https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
  const errorEvent = {
    message: err.stack,
    serviceContext: {
      service: process.env.FUNCTION_NAME,
      resourceType: 'cloud_function',
    },
    context: context,
  };

  // Write the error log entry
  return new Promise((resolve, reject) => {
    log.write(log.entry(metadata, errorEvent), (error) => {
      if (error) {
        return reject(error);
      }
      return resolve();
    });
  });
}

reportError函數可用於手動報告錯誤:

exports.createStripePayment = functions.firestore
  .document('stripe_customers/{userId}/payments/{pushId}')
  .onCreate(async (snap, context) => {
    const { amount, currency, payment_method } = snap.data();
    try {
      // Look up the Stripe customer id.
      const customer = (await snap.ref.parent.parent.get()).data().customer_id;
      // Create a charge using the pushId as the idempotency key
      // to protect against double charges.
      const idempotencyKey = context.params.pushId;
      const payment = await stripe.paymentIntents.create(
        {
          amount,
          currency,
          customer,
          payment_method,
          off_session: false,
          confirm: true,
          confirmation_method: 'manual',
        },
        { idempotencyKey }
      );
      // If the result is successful, write it back to the database.
      await snap.ref.set(payment);
    } catch (error) {
      // We want to capture errors and render them in a user-friendly way, while
      // still logging an exception to Error Reporting.
      functions.logger.log(error);
      await snap.ref.set({ error: userFacingMessage(error) }, { merge: true });
      await reportError(error, { user: context.params.userId });
    }
  });

您可以通過ErrorContext參數傳遞用戶詳細信息。錯誤報告 UI 顯示這些詳細信息並使用它們來計算受影響的用戶數。

ErrorContext也可以傳遞有關 HTTP 請求的信息

export.httpError = functions.https.onRequest((request, response) => {
  const error = new Error('Test error');
  const httpRequest = {
    method: request.method,
    url: request.originalUrl,
    userAgent: request.get('user-agent'),
    referrer: '',
    remoteIp: request.ip
  };
  reportError(error, {httpRequest}).then(() => {
    response.end();
  });
});