mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-11 01:02:01 +03:00
🧹 [code health] Refactor console logging to use dedicated logger utility
🎯 What: Replaced direct `console.*` calls with a new `logger` utility throughout the codebase (application and tests). Use `.bind(console)` to preserve original log origin files. 💡 Why: Centralizes logging logic, making it easier to manage, format, or route logs differently in the future while maintaining observability. ✅ Verification: Ran `npm run test` to ensure all unit tests pass (including updating spy/mocks to target `logger` instead of `console`), and ran `npx tsc --noEmit` to confirm no type regressions. ✨ Result: Improved maintainability and consistent logging across the codebase. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>
This commit is contained in:
parent
b399b95263
commit
2ba2556718
6 changed files with 31 additions and 21 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
// extension API (numi.addUnit / addFunction / setVariable).
|
// extension API (numi.addUnit / addFunction / setVariable).
|
||||||
import { DateOrder, Decimal, EngineSettings, EvalError, Quantity, Unit, Value, XRefError, defaultSettings, qty } from "./types";
|
import { DateOrder, Decimal, EngineSettings, EvalError, Quantity, Unit, Value, XRefError, defaultSettings, qty } from "./types";
|
||||||
import { Registry, buildRegistry, Completion } from "./registry";
|
import { Registry, buildRegistry, Completion } from "./registry";
|
||||||
|
import { logger } from "../utils/logger";
|
||||||
import { tokenize, Token } from "./tokenizer";
|
import { tokenize, Token } from "./tokenizer";
|
||||||
import { parseLine } from "./parser";
|
import { parseLine } from "./parser";
|
||||||
import { evaluate, EvalCtx, XRefResolver, toBase, fromBase } from "./evaluator";
|
import { evaluate, EvalCtx, XRefResolver, toBase, fromBase } from "./evaluator";
|
||||||
|
|
@ -144,7 +145,7 @@ export class SumEngine {
|
||||||
} else {
|
} else {
|
||||||
// Surface unexpected bugs/BigInt errors and log them
|
// Surface unexpected bugs/BigInt errors and log them
|
||||||
lineError = e instanceof Error ? e.message : String(e);
|
lineError = e instanceof Error ? e.message : String(e);
|
||||||
console.warn("evaluate failed:", e);
|
logger.warn("evaluate failed:", e);
|
||||||
}
|
}
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
} from "quickjs-emscripten-core";
|
} from "quickjs-emscripten-core";
|
||||||
import releaseSyncVariant from "@jitl/quickjs-singlefile-browser-release-sync";
|
import releaseSyncVariant from "@jitl/quickjs-singlefile-browser-release-sync";
|
||||||
import { SumEngine, ExtensionUnitSpec, ExtensionValue } from "./engine";
|
import { SumEngine, ExtensionUnitSpec, ExtensionValue } from "./engine";
|
||||||
|
import { logger } from "./utils/logger";
|
||||||
|
|
||||||
interface ExtensionApi {
|
interface ExtensionApi {
|
||||||
setVariable(name: string, value: number | ExtensionValue): void;
|
setVariable(name: string, value: number | ExtensionValue): void;
|
||||||
|
|
@ -75,7 +76,7 @@ export async function runExtensions(
|
||||||
try {
|
try {
|
||||||
await load(engine, scripts);
|
await load(engine, scripts);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("extensions disabled: QuickJS sandbox unavailable:", e);
|
logger.warn("extensions disabled: QuickJS sandbox unavailable:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,7 +201,7 @@ function evaluateScripts(
|
||||||
}
|
}
|
||||||
res.value.dispose();
|
res.value.dispose();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`extension ${s.name} failed:`, e);
|
logger.error(`extension ${s.name} failed:`, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import type { LineResult } from "./engine";
|
||||||
import { setLang, detectLang, t } from "./i18n";
|
import { setLang, detectLang, t } from "./i18n";
|
||||||
import { runExtensions } from "./extensions";
|
import { runExtensions } from "./extensions";
|
||||||
import { checkForUpdate } from "./updater";
|
import { checkForUpdate } from "./updater";
|
||||||
|
import { logger } from "./utils/logger";
|
||||||
import { Workspace } from "./workspace";
|
import { Workspace } from "./workspace";
|
||||||
import { EN, RU } from "./engine/vocab-data";
|
import { EN, RU } from "./engine/vocab-data";
|
||||||
import { exportSheetImage } from "./ui/export";
|
import { exportSheetImage } from "./ui/export";
|
||||||
|
|
@ -433,7 +434,7 @@ function bindDataDirSettings(): void {
|
||||||
try {
|
try {
|
||||||
await migrateDataDir(settings.dataDir, picked, strategy);
|
await migrateDataDir(settings.dataDir, picked, strategy);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("migrate failed", e);
|
logger.warn("migrate failed", e);
|
||||||
toast(t("folderError"));
|
toast(t("folderError"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -534,7 +535,7 @@ async function registerHotkey(old: string | null, combo: string): Promise<boolea
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("hotkey registration failed", e);
|
logger.warn("hotkey registration failed", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -546,14 +547,14 @@ async function applyAutostart(enabled: boolean): Promise<void> {
|
||||||
if (enabled) await auto.enable();
|
if (enabled) await auto.enable();
|
||||||
else await auto.disable();
|
else await auto.disable();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("autostart failed", e);
|
logger.warn("autostart failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function applyAlwaysOnTop(enabled: boolean): Promise<void> {
|
async function applyAlwaysOnTop(enabled: boolean): Promise<void> {
|
||||||
if (!isTauri()) return;
|
if (!isTauri()) return;
|
||||||
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
const { getCurrentWindow } = await import("@tauri-apps/api/window");
|
||||||
await getCurrentWindow().setAlwaysOnTop(enabled).catch((e) => console.warn("always-on-top failed", e));
|
await getCurrentWindow().setAlwaysOnTop(enabled).catch((e) => logger.warn("always-on-top failed", e));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refreshRates(force = false): Promise<void> {
|
async function refreshRates(force = false): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Storage: Tauri commands in the app, localStorage fallback for `vite dev`.
|
// Storage: Tauri commands in the app, localStorage fallback for `vite dev`.
|
||||||
|
import { logger } from "./utils/logger";
|
||||||
|
|
||||||
export interface DocMeta {
|
export interface DocMeta {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -79,7 +80,7 @@ export async function loadSettings(): Promise<SettingsData> {
|
||||||
: localStorage.getItem("summarum.settings");
|
: localStorage.getItem("summarum.settings");
|
||||||
if (raw) return { ...defaultSettingsData, ...JSON.parse(raw) };
|
if (raw) return { ...defaultSettingsData, ...JSON.parse(raw) };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("loadSettings failed", e);
|
logger.warn("loadSettings failed", e);
|
||||||
}
|
}
|
||||||
return { ...defaultSettingsData };
|
return { ...defaultSettingsData };
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +100,7 @@ export async function loadAppData(dataDir: string): Promise<AppData | null> {
|
||||||
: localStorage.getItem("summarum.documents");
|
: localStorage.getItem("summarum.documents");
|
||||||
if (raw) return JSON.parse(raw);
|
if (raw) return JSON.parse(raw);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("loadAppData failed", e);
|
logger.warn("loadAppData failed", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +133,7 @@ export async function flushAppData(): Promise<void> {
|
||||||
if (isTauri()) await invoke("save_documents", { dir: dirArg(currentDataDir), contents: raw });
|
if (isTauri()) await invoke("save_documents", { dir: dirArg(currentDataDir), contents: raw });
|
||||||
else localStorage.setItem("summarum.documents", raw);
|
else localStorage.setItem("summarum.documents", raw);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("saveAppData failed", e);
|
logger.warn("saveAppData failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,7 +151,7 @@ export async function runBackups(dataDir: string, retentionDays: number): Promis
|
||||||
try {
|
try {
|
||||||
await invoke("run_backups", { dir: dirArg(dataDir), retentionDays });
|
await invoke("run_backups", { dir: dirArg(dataDir), retentionDays });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("runBackups failed", e);
|
logger.warn("runBackups failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +160,7 @@ export async function backupDeletedSheet(dataDir: string, title: string, content
|
||||||
try {
|
try {
|
||||||
await invoke("backup_deleted_sheet", { dir: dirArg(dataDir), title, contents });
|
await invoke("backup_deleted_sheet", { dir: dirArg(dataDir), title, contents });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("backupDeletedSheet failed", e);
|
logger.warn("backupDeletedSheet failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +206,7 @@ export async function fetchRates(force = false): Promise<RatesPayload | null> {
|
||||||
return { date: json.time_last_update_utc, rates: json.rates, fetchedAt: Math.floor(Date.now() / 1000) };
|
return { date: json.time_last_update_utc, rates: json.rates, fetchedAt: Math.floor(Date.now() / 1000) };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("fetchRates failed", e);
|
logger.warn("fetchRates failed", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -227,7 +228,7 @@ export async function fetchHistoricalRatesBatch(dates: string[]): Promise<Record
|
||||||
);
|
);
|
||||||
return results;
|
return results;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("fetchHistoricalRatesBatch failed", e);
|
logger.warn("fetchHistoricalRatesBatch failed", e);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -246,7 +247,7 @@ export async function fetchHistoricalRates(date: string): Promise<Record<string,
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("fetchHistoricalRates failed", date, e);
|
logger.warn("fetchHistoricalRates failed", date, e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +266,7 @@ export async function fetchMarketData(symbols: string[]): Promise<Record<string,
|
||||||
try {
|
try {
|
||||||
return await invoke<Record<string, number>>("fetch_market_data", { symbols });
|
return await invoke<Record<string, number>>("fetch_market_data", { symbols });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("fetchMarketData failed", e);
|
logger.warn("fetchMarketData failed", e);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -277,7 +278,7 @@ export async function loadExtensionScripts(): Promise<{ name: string; code: stri
|
||||||
try {
|
try {
|
||||||
return await invoke<{ name: string; code: string }[]>("load_extensions");
|
return await invoke<{ name: string; code: string }[]>("load_extensions");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("loadExtensions failed", e);
|
logger.warn("loadExtensions failed", e);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -314,7 +315,7 @@ export async function onFileDrop(cb: (content: string) => void): Promise<void> {
|
||||||
const content = await invoke<string>("read_text_file", { path });
|
const content = await invoke<string>("read_text_file", { path });
|
||||||
cb(content);
|
cb(content);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("file drop rejected", path, e);
|
logger.warn("file drop rejected", path, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { isTauri } from "./storage";
|
import { isTauri } from "./storage";
|
||||||
|
import { logger } from "./utils/logger";
|
||||||
|
|
||||||
interface AvailableUpdate {
|
interface AvailableUpdate {
|
||||||
version: string;
|
version: string;
|
||||||
|
|
@ -19,10 +20,10 @@ export async function checkForUpdate(): Promise<AvailableUpdate | null | "error"
|
||||||
// visible in devtools console — the fastest way to tell "already on
|
// visible in devtools console — the fastest way to tell "already on
|
||||||
// the latest published release" apart from "the check silently failed"
|
// the latest published release" apart from "the check silently failed"
|
||||||
const { getVersion } = await import("@tauri-apps/api/app");
|
const { getVersion } = await import("@tauri-apps/api/app");
|
||||||
console.info(`no update: running ${await getVersion()}, that's the latest published release`);
|
logger.info(`no update: running ${await getVersion()}, that's the latest published release`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
console.info(`update available: ${update.currentVersion} -> ${update.version}`);
|
logger.info(`update available: ${update.currentVersion} -> ${update.version}`);
|
||||||
return {
|
return {
|
||||||
version: update.version,
|
version: update.version,
|
||||||
async install() {
|
async install() {
|
||||||
|
|
@ -32,7 +33,7 @@ export async function checkForUpdate(): Promise<AvailableUpdate | null | "error"
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("update check failed", e);
|
logger.warn("update check failed", e);
|
||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
src/utils/logger.ts
Normal file
5
src/utils/logger.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const logger = {
|
||||||
|
info: console.info.bind(console),
|
||||||
|
warn: console.warn.bind(console),
|
||||||
|
error: console.error.bind(console),
|
||||||
|
};
|
||||||
Loading…
Add table
Reference in a new issue