Browse Source

refactor: replace console.log with logger utility

- Replace all console.log statements with appropriate logger methods in QRScannerDialog.vue
- Replace console.log statements with logger methods in WebDialogQRScanner.ts
- Fix TypeScript type for failsafeTimeout from 'any' to 'unknown'
- Update LogCollector.ts to use 'unknown' type instead of 'any'
- Add eslint-disable comments for console overrides in LogCollector

This change improves logging consistency across the application by using the centralized logger utility, which provides better error handling, log persistence, and environment-aware logging.
pull/133/head
Matt Raymer 3 weeks ago
parent
commit
0f9826a39d
  1. 230
      src/components/QRScanner/QRScannerDialog.vue
  2. 60
      src/services/QRScanner/WebDialogQRScanner.ts
  3. 8
      src/utils/LogCollector.ts

230
src/components/QRScanner/QRScannerDialog.vue

@ -298,14 +298,14 @@ export default class QRScannerDialog extends Vue {
errorMessage = ""; errorMessage = "";
created() { created() {
console.log('[QRScannerDialog] created'); logger.log("[QRScannerDialog] created");
console.log('[QRScannerDialog] Props received:', { logger.log("[QRScannerDialog] Props received:", {
onScan: typeof this.onScan, onScan: typeof this.onScan,
onError: typeof this.onError, onError: typeof this.onError,
options: this.options, options: this.options,
onClose: typeof this.onClose, onClose: typeof this.onClose,
}); });
console.log('[QRScannerDialog] Initial state:', { logger.log("[QRScannerDialog] Initial state:", {
visible: this.visible, visible: this.visible,
error: this.error, error: this.error,
useQRReader: this.useQRReader, useQRReader: this.useQRReader,
@ -336,61 +336,69 @@ export default class QRScannerDialog extends Vue {
} }
mounted() { mounted() {
console.log('[QRScannerDialog] mounted'); logger.log("[QRScannerDialog] mounted");
// Timer to warn if no QR code detected after 10 seconds // Timer to warn if no QR code detected after 10 seconds
this._scanTimeout = setTimeout(() => { this._scanTimeout = setTimeout(() => {
if (!this.isScanning) { if (!this.isScanning) {
console.warn('[QRScannerDialog] No QR code detected after 10 seconds'); logger.warn("[QRScannerDialog] No QR code detected after 10 seconds");
} }
}, 10000); }, 10000);
// Periodic timer to log waiting status every 5 seconds // Periodic timer to log waiting status every 5 seconds
this._waitingInterval = setInterval(() => { this._waitingInterval = setInterval(() => {
if (!this.isScanning && this.cameraStatus === 'Active') { if (!this.isScanning && this.cameraStatus === "Active") {
console.log('[QRScannerDialog] Still waiting for QR code detection...'); logger.log("[QRScannerDialog] Still waiting for QR code detection...");
} }
}, 5000); }, 5000);
console.log('[QRScannerDialog] Waiting interval started'); logger.log("[QRScannerDialog] Waiting interval started");
} }
beforeUnmount() { beforeUnmount() {
if (this._scanTimeout) { if (this._scanTimeout) {
clearTimeout(this._scanTimeout); clearTimeout(this._scanTimeout);
console.log('[QRScannerDialog] Scan timeout cleared'); logger.log("[QRScannerDialog] Scan timeout cleared");
} }
if (this._waitingInterval) { if (this._waitingInterval) {
clearInterval(this._waitingInterval); clearInterval(this._waitingInterval);
console.log('[QRScannerDialog] Waiting interval cleared'); logger.log("[QRScannerDialog] Waiting interval cleared");
} }
console.log('[QRScannerDialog] beforeUnmount'); logger.log("[QRScannerDialog] beforeUnmount");
} }
async onInit(promise: Promise<void>): Promise<void> { async onInit(promise: Promise<void>): Promise<void> {
console.log('[QRScannerDialog] onInit called'); logger.log("[QRScannerDialog] onInit called");
if (this.isNativePlatform) { if (this.isNativePlatform) {
logger.log("Closing QR dialog on native platform"); logger.log("Closing QR dialog on native platform");
this.$nextTick(() => this.close()); this.$nextTick(() => this.close());
return; return;
} }
this.isInitializing = true; this.isInitializing = true;
console.log('[QRScannerDialog] isInitializing set to', this.isInitializing); logger.log("[QRScannerDialog] isInitializing set to", this.isInitializing);
this.error = null; this.error = null;
this.initializationStatus = "Checking camera access..."; this.initializationStatus = "Checking camera access...";
console.log('[QRScannerDialog] initializationStatus set to', this.initializationStatus); logger.log(
"[QRScannerDialog] initializationStatus set to",
this.initializationStatus,
);
try { try {
if (!navigator.mediaDevices) { if (!navigator.mediaDevices) {
console.log('[QRScannerDialog] Camera API not available'); logger.log("[QRScannerDialog] Camera API not available");
throw new Error( throw new Error(
"Camera API not available. Please ensure you're using HTTPS.", "Camera API not available. Please ensure you're using HTTPS.",
); );
} }
const devices = await navigator.mediaDevices.enumerateDevices(); const devices = await navigator.mediaDevices.enumerateDevices();
const videoDevices = devices.filter((device) => device.kind === "videoinput"); const videoDevices = devices.filter(
console.log('[QRScannerDialog] videoDevices found:', videoDevices.length); (device) => device.kind === "videoinput",
);
logger.log("[QRScannerDialog] videoDevices found:", videoDevices.length);
if (videoDevices.length === 0) { if (videoDevices.length === 0) {
throw new Error("No camera found on this device"); throw new Error("No camera found on this device");
} }
this.initializationStatus = "Requesting camera permission..."; this.initializationStatus = "Requesting camera permission...";
console.log('[QRScannerDialog] initializationStatus set to', this.initializationStatus); logger.log(
"[QRScannerDialog] initializationStatus set to",
this.initializationStatus,
);
try { try {
const stream = await navigator.mediaDevices.getUserMedia({ const stream = await navigator.mediaDevices.getUserMedia({
video: { video: {
@ -401,10 +409,17 @@ export default class QRScannerDialog extends Vue {
}); });
stream.getTracks().forEach((track) => track.stop()); stream.getTracks().forEach((track) => track.stop());
this.initializationStatus = "Camera permission granted..."; this.initializationStatus = "Camera permission granted...";
console.log('[QRScannerDialog] initializationStatus set to', this.initializationStatus); logger.log(
"[QRScannerDialog] initializationStatus set to",
this.initializationStatus,
);
} catch (permissionError) { } catch (permissionError) {
const error = permissionError as Error; const error = permissionError as Error;
console.log('[QRScannerDialog] Camera permission error:', error.name, error.message); logger.log(
"[QRScannerDialog] Camera permission error:",
error.name,
error.message,
);
if ( if (
error.name === "NotAllowedError" || error.name === "NotAllowedError" ||
error.name === "PermissionDeniedError" error.name === "PermissionDeniedError"
@ -429,67 +444,94 @@ export default class QRScannerDialog extends Vue {
} }
} }
this.initializationStatus = "Starting QR scanner..."; this.initializationStatus = "Starting QR scanner...";
console.log('[QRScannerDialog] initializationStatus set to', this.initializationStatus); logger.log(
"[QRScannerDialog] initializationStatus set to",
this.initializationStatus,
);
await promise; await promise;
this.isInitializing = false; this.isInitializing = false;
this.cameraStatus = "Ready"; this.cameraStatus = "Ready";
console.log('[QRScannerDialog] QR scanner initialized successfully'); logger.log("[QRScannerDialog] QR scanner initialized successfully");
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
} catch (error) { } catch (error) {
const wrappedError = error instanceof Error ? error : new Error(String(error)); const wrappedError =
error instanceof Error ? error : new Error(String(error));
this.error = wrappedError.message; this.error = wrappedError.message;
this.cameraStatus = "Error"; this.cameraStatus = "Error";
console.log('[QRScannerDialog] Error initializing QR scanner:', wrappedError.message); logger.log(
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); "[QRScannerDialog] Error initializing QR scanner:",
wrappedError.message,
);
logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
if (this.onError) { if (this.onError) {
this.onError(wrappedError); this.onError(wrappedError);
} }
} finally { } finally {
this.isInitializing = false; this.isInitializing = false;
console.log('[QRScannerDialog] isInitializing set to', this.isInitializing); logger.log(
"[QRScannerDialog] isInitializing set to",
this.isInitializing,
);
} }
} }
onCameraOn(): void { onCameraOn(): void {
this.cameraStatus = "Active"; this.cameraStatus = "Active";
console.log('[QRScannerDialog] Camera turned on successfully'); logger.log("[QRScannerDialog] Camera turned on successfully");
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
} }
onCameraOff(): void { onCameraOff(): void {
this.cameraStatus = "Off"; this.cameraStatus = "Off";
console.log('[QRScannerDialog] Camera turned off'); logger.log("[QRScannerDialog] Camera turned off");
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
} }
onDetect(result: DetectionResult | Promise<DetectionResult>): void { onDetect(result: DetectionResult | Promise<DetectionResult>): void {
const ts = new Date().toISOString(); const ts = new Date().toISOString();
console.log(`[QRScannerDialog] onDetect called at ${ts} with`, result); logger.log(`[QRScannerDialog] onDetect called at ${ts} with`, result);
this.isScanning = true; this.isScanning = true;
this.cameraStatus = "Detecting"; this.cameraStatus = "Detecting";
console.log('[QRScannerDialog] isScanning set to', this.isScanning); logger.log("[QRScannerDialog] isScanning set to", this.isScanning);
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
const processResult = (detection: DetectionResult | DetectionResult[]) => { const processResult = (detection: DetectionResult | DetectionResult[]) => {
try { try {
console.log(`[QRScannerDialog] onDetect exit at ${new Date().toISOString()} with detection:`, detection); logger.log(
`[QRScannerDialog] onDetect exit at ${new Date().toISOString()} with detection:`,
detection,
);
// Fallback: If detection is an array, check the first element // Fallback: If detection is an array, check the first element
let rawValue: string | undefined; let rawValue: string | undefined;
if (Array.isArray(detection) && detection.length > 0 && 'rawValue' in detection[0]) { if (
Array.isArray(detection) &&
detection.length > 0 &&
"rawValue" in detection[0]
) {
rawValue = detection[0].rawValue; rawValue = detection[0].rawValue;
} else if (detection && typeof detection === 'object' && 'rawValue' in detection && detection.rawValue) { } else if (
rawValue = (detection as any).rawValue; detection &&
typeof detection === "object" &&
"rawValue" in detection &&
detection.rawValue
) {
rawValue = (detection as unknown).rawValue;
} }
if (rawValue) { if (rawValue) {
console.log('[QRScannerDialog] Fallback: Detected rawValue, treating as scan:', rawValue); logger.log(
"[QRScannerDialog] Fallback: Detected rawValue, treating as scan:",
rawValue,
);
this.isInitializing = false; this.isInitializing = false;
this.initializationStatus = 'QR code captured!'; this.initializationStatus = "QR code captured!";
this.onScan(rawValue); this.onScan(rawValue);
try { try {
console.log('[QRScannerDialog] About to call close() after scan'); logger.log("[QRScannerDialog] About to call close() after scan");
this.close(); this.close();
console.log('[QRScannerDialog] close() called successfully after scan'); logger.log(
"[QRScannerDialog] close() called successfully after scan",
);
} catch (err) { } catch (err) {
console.error('[QRScannerDialog] Error calling close():', err); logger.error("[QRScannerDialog] Error calling close():", err);
} }
} }
} catch (error) { } catch (error) {
@ -497,8 +539,8 @@ export default class QRScannerDialog extends Vue {
} finally { } finally {
this.isScanning = false; this.isScanning = false;
this.cameraStatus = "Active"; this.cameraStatus = "Active";
console.log('[QRScannerDialog] isScanning set to', this.isScanning); logger.log("[QRScannerDialog] isScanning set to", this.isScanning);
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
} }
}; };
if (result instanceof Promise) { if (result instanceof Promise) {
@ -508,8 +550,11 @@ export default class QRScannerDialog extends Vue {
.finally(() => { .finally(() => {
this.isScanning = false; this.isScanning = false;
this.cameraStatus = "Active"; this.cameraStatus = "Active";
console.log('[QRScannerDialog] isScanning set to', this.isScanning); logger.log("[QRScannerDialog] isScanning set to", this.isScanning);
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log(
"[QRScannerDialog] cameraStatus set to",
this.cameraStatus,
);
}); });
} else { } else {
processResult(result); processResult(result);
@ -517,11 +562,12 @@ export default class QRScannerDialog extends Vue {
} }
private handleError(error: unknown): void { private handleError(error: unknown): void {
const wrappedError = error instanceof Error ? error : new Error(String(error)); const wrappedError =
error instanceof Error ? error : new Error(String(error));
this.error = wrappedError.message; this.error = wrappedError.message;
this.cameraStatus = "Error"; this.cameraStatus = "Error";
console.log('[QRScannerDialog] handleError:', wrappedError.message); logger.log("[QRScannerDialog] handleError:", wrappedError.message);
console.log('[QRScannerDialog] cameraStatus set to', this.cameraStatus); logger.log("[QRScannerDialog] cameraStatus set to", this.cameraStatus);
if (this.onError) { if (this.onError) {
this.onError(wrappedError); this.onError(wrappedError);
} }
@ -529,14 +575,24 @@ export default class QRScannerDialog extends Vue {
onDecode(result: string): void { onDecode(result: string): void {
const ts = new Date().toISOString(); const ts = new Date().toISOString();
console.log(`[QRScannerDialog] onDecode called at ${ts} with result:`, result); logger.log(
`[QRScannerDialog] onDecode called at ${ts} with result:`,
result,
);
try { try {
this.isInitializing = false; this.isInitializing = false;
this.initializationStatus = 'QR code captured!'; this.initializationStatus = "QR code captured!";
console.log('[QRScannerDialog] UI state updated after scan: isInitializing set to', this.isInitializing, ', initializationStatus set to', this.initializationStatus); logger.log(
"[QRScannerDialog] UI state updated after scan: isInitializing set to",
this.isInitializing,
", initializationStatus set to",
this.initializationStatus,
);
this.onScan(result); this.onScan(result);
this.close(); this.close();
console.log(`[QRScannerDialog] onDecode exit at ${new Date().toISOString()}`); logger.log(
`[QRScannerDialog] onDecode exit at ${new Date().toISOString()}`,
);
} catch (error) { } catch (error) {
this.handleError(error); this.handleError(error);
} }
@ -544,77 +600,95 @@ export default class QRScannerDialog extends Vue {
toggleCamera(): void { toggleCamera(): void {
const prevCamera = this.preferredCamera; const prevCamera = this.preferredCamera;
this.preferredCamera = this.preferredCamera === "user" ? "environment" : "user"; this.preferredCamera =
console.log('[QRScannerDialog] toggleCamera from', prevCamera, 'to', this.preferredCamera); this.preferredCamera === "user" ? "environment" : "user";
console.log('[QRScannerDialog] preferredCamera set to', this.preferredCamera); logger.log(
"[QRScannerDialog] toggleCamera from",
prevCamera,
"to",
this.preferredCamera,
);
logger.log(
"[QRScannerDialog] preferredCamera set to",
this.preferredCamera,
);
} }
retryScanning(): void { retryScanning(): void {
console.log('[QRScannerDialog] retryScanning called'); logger.log("[QRScannerDialog] retryScanning called");
this.error = null; this.error = null;
this.isInitializing = true; this.isInitializing = true;
console.log('[QRScannerDialog] isInitializing set to', this.isInitializing); logger.log("[QRScannerDialog] isInitializing set to", this.isInitializing);
console.log('[QRScannerDialog] Scanning re-initialized'); logger.log("[QRScannerDialog] Scanning re-initialized");
} }
close = async (): Promise<void> => { close = async (): Promise<void> => {
console.log('[QRScannerDialog] close called'); logger.log("[QRScannerDialog] close called");
this.visible = false; this.visible = false;
console.log('[QRScannerDialog] visible set to', this.visible); logger.log("[QRScannerDialog] visible set to", this.visible);
// Notify parent/service // Notify parent/service
if (typeof this.onClose === 'function') { if (typeof this.onClose === "function") {
console.log('[QRScannerDialog] Calling onClose prop'); logger.log("[QRScannerDialog] Calling onClose prop");
this.onClose(); this.onClose();
} }
await this.$nextTick(); await this.$nextTick();
if (this.$el && this.$el.parentNode) { if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el); this.$el.parentNode.removeChild(this.$el);
console.log('[QRScannerDialog] Dialog element removed from DOM'); logger.log("[QRScannerDialog] Dialog element removed from DOM");
} else { } else {
console.log('[QRScannerDialog] Dialog element NOT removed from DOM'); logger.log("[QRScannerDialog] Dialog element NOT removed from DOM");
} }
} };
onScanDetect(promisedResult) { onScanDetect(promisedResult) {
const ts = new Date().toISOString(); const ts = new Date().toISOString();
console.log(`[QRScannerDialog] onScanDetect called at ${ts} with`, promisedResult); logger.log(
`[QRScannerDialog] onScanDetect called at ${ts} with`,
promisedResult,
);
promisedResult promisedResult
.then((result) => { .then((result) => {
console.log(`[QRScannerDialog] onScanDetect exit at ${new Date().toISOString()} with result:`, result); logger.log(
`[QRScannerDialog] onScanDetect exit at ${new Date().toISOString()} with result:`,
result,
);
this.onScan(result); this.onScan(result);
}) })
.catch((error) => { .catch((error) => {
console.error(`[QRScannerDialog] onScanDetect error at ${new Date().toISOString()}:`, error); logger.error(
this.errorMessage = error.message || 'Scan error'; `[QRScannerDialog] onScanDetect error at ${new Date().toISOString()}:`,
error,
);
this.errorMessage = error.message || "Scan error";
if (this.onError) this.onError(error); if (this.onError) this.onError(error);
}); });
} }
onScanError(error) { onScanError(error) {
const ts = new Date().toISOString(); const ts = new Date().toISOString();
console.error(`[QRScannerDialog] onScanError called at ${ts}:`, error); logger.error(`[QRScannerDialog] onScanError called at ${ts}:`, error);
this.errorMessage = error.message || 'Camera error'; this.errorMessage = error.message || "Camera error";
if (this.onError) this.onError(error); if (this.onError) this.onError(error);
} }
async startMobileScan() { async startMobileScan() {
try { try {
console.log('[QRScannerDialog] startMobileScan called'); logger.log("[QRScannerDialog] startMobileScan called");
const scanner = QRScannerFactory.getInstance(); const scanner = QRScannerFactory.getInstance();
await scanner.startScan(); await scanner.startScan();
} catch (error) { } catch (error) {
console.error('[QRScannerDialog] Error starting mobile scan:', error); logger.error("[QRScannerDialog] Error starting mobile scan:", error);
if (this.onError) this.onError(error); if (this.onError) this.onError(error);
} }
} }
async copyLogs() { async copyLogs() {
console.log('[QRScannerDialog] copyLogs called'); logger.log("[QRScannerDialog] copyLogs called");
try { try {
await navigator.clipboard.writeText(logCollector.getLogs()); await navigator.clipboard.writeText(logCollector.getLogs());
alert('Logs copied to clipboard!'); alert("Logs copied to clipboard!");
} catch (e) { } catch (e) {
alert('Failed to copy logs: ' + (e instanceof Error ? e.message : e)); alert("Failed to copy logs: " + (e instanceof Error ? e.message : e));
} }
} }
} }

60
src/services/QRScanner/WebDialogQRScanner.ts

@ -10,20 +10,20 @@ export class WebDialogQRScanner implements QRScannerService {
private isScanning = false; private isScanning = false;
private container: HTMLElement | null = null; private container: HTMLElement | null = null;
private sessionId: number | null = null; private sessionId: number | null = null;
private failsafeTimeout: any = null; private failsafeTimeout: unknown = null;
constructor(private options?: QRScannerOptions) {} constructor(private options?: QRScannerOptions) {}
async checkPermissions(): Promise<boolean> { async checkPermissions(): Promise<boolean> {
try { try {
console.log("[QRScanner] Checking camera permissions..."); logger.log("[QRScanner] Checking camera permissions...");
const permissions = await navigator.permissions.query({ const permissions = await navigator.permissions.query({
name: "camera" as PermissionName, name: "camera" as PermissionName,
}); });
console.log("[QRScanner] Permission state:", permissions.state); logger.log("[QRScanner] Permission state:", permissions.state);
return permissions.state === "granted"; return permissions.state === "granted";
} catch (error) { } catch (error) {
console.error("[QRScanner] Error checking camera permissions:", error); logger.error("[QRScanner] Error checking camera permissions:", error);
return false; return false;
} }
} }
@ -129,7 +129,9 @@ export class WebDialogQRScanner implements QRScannerService {
try { try {
this.isScanning = true; this.isScanning = true;
this.sessionId = Date.now(); this.sessionId = Date.now();
console.log(`[WebDialogQRScanner] Opening dialog, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] Opening dialog, session: ${this.sessionId}`,
);
// Create and mount dialog component // Create and mount dialog component
this.container = document.createElement("div"); this.container = document.createElement("div");
@ -147,23 +149,31 @@ export class WebDialogQRScanner implements QRScannerService {
} }
}, },
onClose: () => { onClose: () => {
console.log(`[WebDialogQRScanner] onClose received from dialog, session: ${this.sessionId}`); logger.log(
this.stopScan('dialog onClose'); `[WebDialogQRScanner] onClose received from dialog, session: ${this.sessionId}`,
);
this.stopScan("dialog onClose");
}, },
options: this.options, options: this.options,
sessionId: this.sessionId, sessionId: this.sessionId,
}); });
this.dialogComponent = this.dialogInstance.mount(this.container) as InstanceType<typeof QRScannerDialog>; this.dialogComponent = this.dialogInstance.mount(
this.container,
) as InstanceType<typeof QRScannerDialog>;
// Failsafe: force cleanup after 60s if dialog is still open // Failsafe: force cleanup after 60s if dialog is still open
this.failsafeTimeout = setTimeout(() => { this.failsafeTimeout = setTimeout(() => {
if (this.isScanning) { if (this.isScanning) {
console.warn(`[WebDialogQRScanner] Failsafe triggered, forcing cleanup for session: ${this.sessionId}`); logger.warn(
this.stopScan('failsafe timeout'); `[WebDialogQRScanner] Failsafe triggered, forcing cleanup for session: ${this.sessionId}`,
);
this.stopScan("failsafe timeout");
} }
}, 60000); }, 60000);
console.log(`[WebDialogQRScanner] Failsafe timeout set for session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] Failsafe timeout set for session: ${this.sessionId}`,
);
} catch (error) { } catch (error) {
this.isScanning = false; this.isScanning = false;
const wrappedError = const wrappedError =
@ -177,20 +187,26 @@ export class WebDialogQRScanner implements QRScannerService {
} }
} }
async stopScan(reason: string = 'manual') : Promise<void> { async stopScan(reason: string = "manual"): Promise<void> {
if (!this.isScanning) { if (!this.isScanning) {
return; return;
} }
try { try {
console.log(`[WebDialogQRScanner] stopScan called, reason: ${reason}, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] stopScan called, reason: ${reason}, session: ${this.sessionId}`,
);
if (this.dialogComponent) { if (this.dialogComponent) {
await this.dialogComponent.close(); await this.dialogComponent.close();
console.log(`[WebDialogQRScanner] dialogComponent.close() called, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] dialogComponent.close() called, session: ${this.sessionId}`,
);
} }
if (this.dialogInstance) { if (this.dialogInstance) {
this.dialogInstance.unmount(); this.dialogInstance.unmount();
console.log(`[WebDialogQRScanner] dialogInstance.unmount() called, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] dialogInstance.unmount() called, session: ${this.sessionId}`,
);
} }
} catch (error) { } catch (error) {
const wrappedError = const wrappedError =
@ -202,7 +218,9 @@ export class WebDialogQRScanner implements QRScannerService {
if (this.failsafeTimeout) { if (this.failsafeTimeout) {
clearTimeout(this.failsafeTimeout); clearTimeout(this.failsafeTimeout);
this.failsafeTimeout = null; this.failsafeTimeout = null;
console.log(`[WebDialogQRScanner] Failsafe timeout cleared, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] Failsafe timeout cleared, session: ${this.sessionId}`,
);
} }
this.cleanupContainer(); this.cleanupContainer();
} }
@ -215,16 +233,20 @@ export class WebDialogQRScanner implements QRScannerService {
private cleanupContainer(): void { private cleanupContainer(): void {
if (this.container && this.container.parentNode) { if (this.container && this.container.parentNode) {
this.container.parentNode.removeChild(this.container); this.container.parentNode.removeChild(this.container);
console.log(`[WebDialogQRScanner] Dialog container removed from DOM, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] Dialog container removed from DOM, session: ${this.sessionId}`,
);
} else { } else {
console.log(`[WebDialogQRScanner] Dialog container NOT removed from DOM, session: ${this.sessionId}`); logger.log(
`[WebDialogQRScanner] Dialog container NOT removed from DOM, session: ${this.sessionId}`,
);
} }
this.container = null; this.container = null;
} }
async cleanup(): Promise<void> { async cleanup(): Promise<void> {
try { try {
await this.stopScan('cleanup'); await this.stopScan("cleanup");
} catch (error) { } catch (error) {
const wrappedError = const wrappedError =
error instanceof Error ? error : new Error(String(error)); error instanceof Error ? error : new Error(String(error));

8
src/utils/LogCollector.ts

@ -2,20 +2,22 @@ type LogLevel = "log" | "info" | "warn" | "error";
interface LogEntry { interface LogEntry {
level: LogLevel; level: LogLevel;
message: any[]; message: unknown[];
timestamp: string; timestamp: string;
} }
class LogCollector { class LogCollector {
private logs: LogEntry[] = []; private logs: LogEntry[] = [];
private originalConsole: Partial< private originalConsole: Partial<
Record<LogLevel, (..._args: any[]) => void> Record<LogLevel, (..._args: unknown[]) => void>
> = {}; > = {};
constructor() { constructor() {
(["log", "info", "warn", "error"] as LogLevel[]).forEach((level) => { (["log", "info", "warn", "error"] as LogLevel[]).forEach((level) => {
// eslint-disable-next-line no-console
this.originalConsole[level] = console[level]; this.originalConsole[level] = console[level];
console[level] = (..._args: any[]) => { // eslint-disable-next-line no-console
console[level] = (..._args: unknown[]) => {
this.logs.push({ this.logs.push({
level, level,
message: _args, message: _args,

Loading…
Cancel
Save