Informa errores

Informa errores automáticamente

Para emitir un error desde una función de Cloud Functions en Error Reporting, haz lo siguiente:

Node.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');

Si quieres obtener un informe de errores más detallado, puedes usar las bibliotecas cliente de Error Reporting.

En GCP Console, puedes ver los errores informados en Error Reporting. También puedes ver los errores informados desde una función en particular cuando lo seleccionas en la lista de funciones de la consola de GCP.

Las excepciones sin detectar que genere la función aparecerán en Error Reporting. Ten en cuenta que algunos tipos de excepciones sin detectar (como las que se arrojan de forma asíncrona) provocarán un inicio en frío en una invocación de función futura. Esto aumentará la cantidad de tiempo que tardará en ejecutarse tu función.

Informe manual de errores

Para informar un error a Error Reporting desde una función, usa la API de Cloud Logging.

Importa dependencias

Desde el directorio functions, instala la biblioteca cliente de Cloud Logging para Node.js:

npm install --save @google-cloud/logging

Importa e inicializa la biblioteca cliente de Cloud Logging:

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

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

Envía datos a Cloud Logging

Una entrada de registro correctamente formulada requiere un objeto MonitoredResource y uno ErrorEvent.

En esta función reportError de ejemplo, se demuestran los datos mínimos obligatorios para informar un error a 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();
    });
  });
}

La función reportError puede usarse para informar errores manualmente:

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 });
    }
  });

Puedes pasar la información del usuario a través del parámetro ErrorContext. Se muestran estos detalles en la IU de Error Reporting y se usan para calcular la cantidad de usuarios afectados.

Asimismo, se puede pasar información a ErrorContext en una solicitud 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();
  });
});