108 lines
3.1 KiB
TypeScript
108 lines
3.1 KiB
TypeScript
import type { HASSDomEvent } from "../common/dom/fire_event";
|
|
import type { SystemLogLevel } from "../data/system_log";
|
|
import type { Constructor } from "../types";
|
|
import type { HassBaseEl } from "./hass-base-mixin";
|
|
|
|
interface WriteLogParams {
|
|
level?: SystemLogLevel;
|
|
message: string;
|
|
}
|
|
|
|
declare global {
|
|
// for fire event
|
|
interface HASSDomEvents {
|
|
write_log: WriteLogParams;
|
|
}
|
|
interface HTMLElementEventMap {
|
|
write_log: HASSDomEvent<WriteLogParams>;
|
|
}
|
|
}
|
|
|
|
export const loggingMixin = <T extends Constructor<HassBaseEl>>(
|
|
superClass: T
|
|
) =>
|
|
class extends superClass {
|
|
protected hassConnected() {
|
|
super.hassConnected();
|
|
window.addEventListener("error", async (ev) => {
|
|
if (!this.hass?.connected) {
|
|
return;
|
|
}
|
|
if (
|
|
!__DEV__ &&
|
|
(ev.message.includes("ResizeObserver loop limit exceeded") ||
|
|
ev.message.includes(
|
|
"ResizeObserver loop completed with undelivered notifications"
|
|
))
|
|
) {
|
|
ev.preventDefault();
|
|
ev.stopImmediatePropagation();
|
|
ev.stopPropagation();
|
|
return;
|
|
}
|
|
try {
|
|
const { createLogMessage } = await import("../resources/log-message");
|
|
const message = await createLogMessage(
|
|
ev.error,
|
|
"Uncaught error",
|
|
// The error object from browsers includes the message and a stack trace,
|
|
// so use the data in the error event just as fallback
|
|
ev.message,
|
|
`@${ev.filename}:${ev.lineno}:${ev.colno}`
|
|
);
|
|
await this._writeLog({ message });
|
|
} catch (e) {
|
|
// catch errors during logging so we don't get into a loop
|
|
// eslint-disable-next-line no-console
|
|
console.error("Failure writing uncaught error to system log:", e);
|
|
}
|
|
});
|
|
window.addEventListener("unhandledrejection", async (ev) => {
|
|
if (!this.hass?.connected) {
|
|
return;
|
|
}
|
|
try {
|
|
const { createLogMessage } = await import("../resources/log-message");
|
|
const message = await createLogMessage(
|
|
ev.reason,
|
|
"Unhandled promise rejection"
|
|
);
|
|
await this._writeLog({
|
|
message,
|
|
level: "debug",
|
|
});
|
|
} catch (e) {
|
|
// catch errors during logging so we don't get into a loop
|
|
// eslint-disable-next-line no-console
|
|
console.error(
|
|
"Failure writing unhandled promise rejection to system log:",
|
|
e
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
protected firstUpdated(changedProps) {
|
|
super.firstUpdated(changedProps);
|
|
this.addEventListener("write_log", (ev) => {
|
|
this._writeLog(ev.detail);
|
|
});
|
|
}
|
|
|
|
private _writeLog(log: WriteLogParams) {
|
|
return this.hass?.callService(
|
|
"system_log",
|
|
"write",
|
|
{
|
|
logger: `frontend.${
|
|
__DEV__ ? "js_dev" : "js"
|
|
}.${__BUILD__}.${__VERSION__.replace(".", "")}`,
|
|
message: log.message,
|
|
level: log.level || "error",
|
|
},
|
|
undefined,
|
|
false
|
|
);
|
|
}
|
|
};
|