@samitouri / QOSami-HFS / commits / ebf8db0c

safer: avoid error in the case of symbols

Massimo Melina committed Sep 19, 2025 at 23:24 UTC ebf8db0cbdc111e209988399ee6677169f97f1c8
4 files changed +21 -4
shared/api.ts
+1 -1
@@ -95,7 +95,7 @@ export function useApi<T=any>(cmd: string | Falsy, params?: object, options: Api
95 useEffect(() => {
96 setError(undefined)
97 const aborted = () => getLoading()?.aborted()
98 - const wholePromise = wait(0) // postpone a bit, so that if it is aborted immediately, it is never really fired (happens mostly in dev mode)
98 + const wholePromise = wait(0) // postpone a bit so that if it is aborted immediately, it is never really fired (happens mostly in dev mode)
99 .then(() => {
100 const ret = !cmd || aborted() ? undefined : apiCall<T>(cmd, params, options)
101 setLoading(ret)
src/consoleLog.ts
+18 -1
@@ -9,7 +9,7 @@ for (const k of ['log','warn','error']) {
9 const original = console[k as 'log']
10 console[k as 'log'] = (...args: any[]) => {
11 const ts = new Date()
12 - const msg = args.join(' ')
12 + const msg = safeJoin(args) // if args contains a symbol, join will throw
13 const rec = { ts, k, msg }
14 consoleLog.push(rec)
15 if (consoleLog.length > 100_000) // limit to avoid infinite space
@@ -21,3 +21,20 @@ for (const k of ['log','warn','error']) {
21 return original(formatTime(ts), ...args) // bundled nodejs doesn't have locales (and apparently uses en-US)
22 }
23 }
24 +
25 +function safeJoin(a: unknown[]): string {
26 + try { return a.join(' ') }
27 + catch {
28 + return a.map(x => {
29 + if (x == null)
30 + return ''
31 + try { return String(x) }
32 + catch {
33 + if (Array.isArray(x))
34 + return `[${safeJoin(x)}]`
35 + try { return JSON.stringify(x) }
36 + catch { return 'N/A' }
37 + }
38 + }).join(' ')
39 + }
40 +}
\ No newline at end of file
src/update.ts
+1 -1
@@ -79,7 +79,7 @@ export async function getVersions(interrupt?: (r: Release) => boolean) {
79 }
80
81 export async function getUpdates(strict=false) {
82 - getProjectInfo() // check for alerts
82 + void getProjectInfo() // also check for alerts and print them asap in the console
83 const stable: Release = prepareRelease(await getRepoInfo(HFS_REPO + '/releases/latest'))
84 const res = await getVersions(r => r.versionScalar < stable.versionScalar) // we don't consider betas before stable
85 const ret = res.filter(x => x.prerelease && (strict ? x.isNewer : (x.versionScalar !== curV)) )
src/walkDir.ts
+1 -1
@@ -134,7 +134,7 @@ export class DirentFromStats extends Dirent {
134
135 for (const key of Reflect.ownKeys(Dirent.prototype)) {
136 const name = key as DirentStatsKeysIntersection | 'constructor';
137 - if (name === 'constructor')
137 + if (name === 'constructor' || typeof name === 'symbol')
138 continue;
139 DirentFromStats.prototype[name] = function () {
140 return this[kStats][name]();