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]();