Automatically reporting errors
You can emit an error from a Cloud Function to Error Reporting as shown below:
Node.js
If you would like more fine-grained error reporting, you can use the Error Reporting client libraries.
You can view the reported errors in Error Reporting in the GCP Console. You can also see the errors reported from a particular function when you select it from the list of functions in the GCP Console.
Uncaught exceptions produced by your function will appear in Error Reporting. Note that some types of uncaught exceptions (such as those thrown asynchronously) will cause a cold start to occur upon a future function invocation. This increases the amount of time your function will take to run.
Manually reporting errors
To report an error to Error Reporting from a function, use the Cloud Logging API.
Importing dependencies
From your functions
directory, install the Cloud Logging client
library for Node.js:
npm install --save @google-cloud/logging
Import and initialize the Cloud Logging client library:
const Logging = require('@google-cloud/logging');
// Instantiates a client
const logging = Logging();
Sending to Cloud Logging
A properly formed log entry requires a MonitoredResource
object and an ErrorEvent
object.
This example reportError
function demonstrates the minimum data required to
report an error to 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(); }); }); }
The reportError
function can be used to manually report errors:
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 }); } });
You can pass user details through the ErrorContext
parameter.
The Error Reporting UI displays these details and uses them to
calculate the number of affected users.
ErrorContext
can also be passed
information on an HTTP Request:
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();
});
});