glean/src/core/error/index.ts (34 lines of code) (raw):

/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import type { ErrorType } from "./error_type.js"; import type { MetricType } from "../metrics/index.js"; import log from "../log.js"; import { InternalCounterMetricType as CounterMetricType } from "../metrics/types/counter.js"; import { combineIdentifierAndLabel, stripLabel } from "../metrics/types/labeled.js"; /** * Create a log tag for a specific metric type. * * @param metric The metric type to create a tag for. * @returns The tag. */ export function createLogTag(metric: MetricType): string { const capitalizedType = metric.type.charAt(0).toUpperCase() + metric.type.slice(1); return `core.metrics.${capitalizedType}`; } /** * For a given metric, get the metric in which to record errors. * * # Important * * Errors do not adhere to the usual "maximum label" restriction. * * @param metric The metric to record an error for. * @param error The error type to record. * @returns The metric to record to. */ export function getErrorMetricForMetric(metric: MetricType, error: ErrorType): CounterMetricType { const identifier = metric.baseIdentifier(); const name = stripLabel(identifier); // We don't use the labeled metric type here, // because we want to bypass the max number of allowed labels. return new CounterMetricType({ name: combineIdentifierAndLabel(error, name), category: "glean.error", lifetime: "ping", // TODO: Also add the metric ping to the list. Depends on Bug 1710838. sendInPings: metric.sendInPings, disabled: false }); } export default class ErrorManager { /** * Records an error into Glean. * * Errors are recorded as labeled counters in the `glean.error` category. * * @param metric The metric to record an error for. * @param error The error type to record. * @param message The message to log. This message is not sent with the ping. * It does not need to include the metric id, as that is automatically * prepended to the message. * @param numErrors The number of errors of the same type to report. */ record(metric: MetricType, error: ErrorType, message: unknown, numErrors = 1): void { const errorMetric = getErrorMetricForMetric(metric, error); log(createLogTag(metric), [`${metric.baseIdentifier()}:`, message]); if (numErrors > 0) { errorMetric.add(numErrors); } } /** * Gets the number of recorded errors for the given metric and error type. * * @param metric The metric to get the number of errors for. * @param error The error type to get count of. * @param ping The ping from which we want to retrieve the number of recorded errors. * Defaults to the first value in `sendInPings`. * @returns The number of errors reported. */ testGetNumRecordedErrors(metric: MetricType, error: ErrorType, ping?: string): number { const errorMetric = getErrorMetricForMetric(metric, error); const numErrors = errorMetric.testGetValue(ping); return numErrors || 0; } }