export function getValidDynamicLabel()

in glean/src/core/metrics/types/labeled.ts [97:143]


export function getValidDynamicLabel(metric: MetricType): string {
  // Note that we assume `metric.dynamicLabel` to always be available within this function.
  // This is a safe assumptions because we should only call `getValidDynamicLabel` if we have
  // a dynamic label.
  if (metric.dynamicLabel === undefined) {
    throw new Error("This point should never be reached.");
  }

  const key = combineIdentifierAndLabel(metric.baseIdentifier(), metric.dynamicLabel);

  for (const ping of metric.sendInPings) {
    if (Context.metricsDatabase.hasMetric(metric.lifetime, ping, metric.type, key)) {
      return key;
    }
  }

  let numUsedKeys = 0;
  for (const ping of metric.sendInPings) {
    numUsedKeys += Context.metricsDatabase.countByBaseIdentifier(
      metric.lifetime,
      ping,
      metric.type,
      metric.baseIdentifier()
    );
  }

  let hitError = false;
  if (numUsedKeys >= MAX_LABELS) {
    hitError = true;
  } else if (metric.dynamicLabel.length > MAX_LABEL_LENGTH) {
    hitError = true;
    Context.errorManager.record(
      metric,
      ErrorType.InvalidLabel,
      `Label length ${metric.dynamicLabel.length} exceeds maximum of ${MAX_LABEL_LENGTH}.`
    );
  } else if (!LABEL_REGEX.test(metric.dynamicLabel)) {
    hitError = true;
    Context.errorManager.record(
      metric,
      ErrorType.InvalidLabel,
      `Label must be snake_case, got '${metric.dynamicLabel}'.`
    );
  }

  return hitError ? combineIdentifierAndLabel(metric.baseIdentifier(), OTHER_LABEL) : key;
}