@snap/camera-kit
Version:
Camera Kit Web
82 lines • 4.08 kB
JavaScript
import { isState } from "@snap/state-management";
import { filter, map, scan, Subject, takeUntil } from "rxjs";
import { Injectable } from "@snap/ts-inject";
import { entries } from "../../common/entries";
import { stringifyError, stringifyErrorMessage } from "../../common/errorHelpers";
import { TypedCustomEvent } from "../../events/TypedCustomEvent";
import { logEntriesFactory } from "../../logger/logEntries";
import { logLevelMap } from "../../logger/logger";
import { metricsEventTargetFactory } from "../metricsEventTarget";
import { metricsClientFactory } from "../../clients/metricsClient";
import { Count } from "../operational/Count";
const logMethods = entries(logLevelMap).map(([level]) => level);
const maxBufferedEntries = 15;
const contextSeparator = "\n\n----------------- Context -----------------\n\n";
const methodLength = logMethods.reduce((max, method) => Math.max(max, method.length), 0);
export function getContextString(logEntries) {
const result = [];
for (const { entry, count, lastTime } of logEntries) {
const time = entry.time.toISOString();
const method = entry.level.padStart(methodLength);
const messages = entry.messages.map(prettyPrintMessage).join(" ");
let dupSuffix = count > 1 ? ` (Repeated ${count} times with the last occurrence at ${lastTime.toISOString()})` : "";
result.push(`${time} [${entry.module}] ${method}: ${messages}${dupSuffix}`);
}
return result.join("\n");
}
function prettyPrintMessage(message) {
if (message instanceof Error)
return stringifyErrorMessage(message);
if (message instanceof Date)
return message.toISOString();
return message + "";
}
export function reportExceptionToBlizzard(logEntries, metricsEventTarget, metrics, lensState) {
logEntries
.pipe(scan(({ entries }, newEntry) => {
const lastEntry = entries[entries.length - 1];
const isNewEntryRepeated = lastEntry &&
lastEntry.entry.messages.join() === newEntry.messages.join() &&
lastEntry.entry.level === newEntry.level;
if (isNewEntryRepeated) {
lastEntry.count += 1;
lastEntry.lastTime = newEntry.time;
}
else {
entries.push({
entry: newEntry,
count: 1,
lastTime: newEntry.time,
});
}
return {
entries: entries.slice(-maxBufferedEntries),
recent: newEntry,
};
}, { entries: [], recent: { time: new Date(), module: "any", level: "debug", messages: [] } }), filter(({ recent }) => recent.level === "error"), map(({ entries, recent }) => ({
context: entries,
error: recent.messages.find((e) => e instanceof Error),
})), filter(({ error }) => !!error))
.subscribe(({ error, context }) => {
const currentLensState = lensState === null || lensState === void 0 ? void 0 : lensState.getState();
const lensId = currentLensState && !isState(currentLensState, "noLensApplied") ? currentLensState.data.id : "none";
metricsEventTarget.dispatchEvent(new TypedCustomEvent("exception", {
name: "exception",
lensId,
type: error.name,
reason: `${stringifyError(error)}${contextSeparator}${getContextString(context)}`,
}));
metrics.setOperationalMetrics(Count.count("handled_exception", 1, { type: error.name }));
});
}
export const reportGlobalException = Injectable("reportGlobalException", [logEntriesFactory.token, metricsEventTargetFactory.token, metricsClientFactory.token], (logEntries, metricsEventTarget, metrics) => {
const cancellationSubject = new Subject();
reportExceptionToBlizzard(logEntries.pipe(takeUntil(cancellationSubject)), metricsEventTarget, metrics);
return {
attachLensContext: (lensState) => {
cancellationSubject.next();
reportExceptionToBlizzard(logEntries, metricsEventTarget, metrics, lensState);
},
};
});
//# sourceMappingURL=reportGlobalException.js.map