Errors emitted from your function are automatically captured and reported in Stackdriver Error Reporting if they produce a stack trace.
Automatically reporting errors
With the Firebase SDK for Cloud Functions this applies to any uncaught exceptions and any
errors you throw that are of type Error.
For example, the following error is captured by Stackdriver Error Reporting:
export.helloError = functions.https.onRequest((request, response) => {
// This will be reported to Stackdriver Error Reporting
throw new Error('epic fail');
});
The following error is not captured by Stackdriver Error Reporting:
export.errorFail = functions.https.onRequest((request, response) => {
// This will NOT be reported to Stackdriver Error Reporting
throw 1;
});
Viewing errors
You can view reported errors in the Google Platform Console.
Manually reporting errors
To report an error to Stackdriver Error Reporting from a function, use the Stackdriver Logging API.
Importing dependencies
From your functions directory, install the Google Stackdriver Logging Client
Library for Node.js:
npm install --save @google-cloud/logging
Import the Google Cloud Client Library to access the Logging API:
const Logging = require('@google-cloud/logging');
// Instantiates a client
const logging = Logging();
Sending to Stackdriver
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 Stackdriver Error Reporting.
function reportError(err, context = {}) {
// This is the name of the StackDriver 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 StackDriver 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) { reject(error); }
resolve();
});
});
}
The reportError function can be used to manually report errors, which had
otherwise been caught:
// Charge the Stripe customer whenever an amount is written to the Realtime database
exports.createStripeCharge = functions.database.ref('/stripe_customers/{userId}/charges/{id}').onWrite(event => {
const val = event.data.val();
// This onWrite will trigger whenever anything is written to the path, so
// noop if the charge was deleted, errored out, or the Stripe API returned a result (id exists)
if (val === null || val.id || val.error) return null;
// Look up the Stripe customer id written in createStripeCustomer
return admin.database().ref(`/stripe_customers/${event.params.userId}/customer_id`).once('value').then(snapshot => {
return snapshot.val();
}).then(customer => {
// Create a charge using the pushId as the idempotency key, protecting against double charges
const amount = val.amount;
const idempotency_key = event.params.id;
let charge = {amount, currency, customer};
if (val.source !== null) charge.source = val.source;
return stripe.charges.create(charge, {idempotency_key});
}).then(response => {
// If the result is successful, write it back to the database
return event.data.adminRef.set(response);
}, error => {
// We want to capture errors and render them in a user-friendly way, while
// still logging an exception with Stackdriver
return event.data.adminRef.child('error').set(userFacingMessage(error)).then(() => {
return reportError(error, {user: event.params.userId});
});
}
);
});
User details can be passed through the ErrorContext parameter
to be displayed in the Stackdriver UI and used 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 = httpRequest = {
method: request.method,
url: request.originalUrl,
userAgent: request.get('user-agent'),
referrer: '',
remoteIp: request.ip
};
reportError(error, {httpRequest}).then(() => {
response.end();
});
});

