-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ses): Consistently name console methods (#2654)
Ref #2643 Ref 5e8fd33 Unify the inconsistent approaches to creating [virtual] console functions with appropriate "name" properties.
- Loading branch information
Showing
1 changed file
with
34 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,20 @@ import { | |
* @import {ErrorInfo, ErrorInfoKind, LogRecord, NoteCallback, LoggedErrorHandler, MakeCausalConsole, MakeLoggingConsoleKit} from "./internal-types.js"; | ||
*/ | ||
|
||
/** | ||
* Explicitly set a function's name, supporting use of arrow functions for which | ||
* source text doesn't include a name and no initial name is set by | ||
* NamedEvaluation | ||
* https://tc39.es/ecma262/multipage/syntax-directed-operations.html#sec-runtime-semantics-namedevaluation | ||
* Instead, we hope that tooling uses only the explicit `name` property. | ||
* | ||
* @template {function} T | ||
Check warning on line 38 in packages/ses/src/error/console.js GitHub Actions / lint
|
||
* @param {string} name | ||
* @param {T} fn | ||
* @returns {T} | ||
*/ | ||
const defineName = (name, fn) => defineProperty(fn, 'name', { value: name }); | ||
|
||
// For our internal debugging purposes, uncomment | ||
// const internalDebugConsole = console; | ||
|
||
|
@@ -159,16 +173,12 @@ export const makeLoggingConsoleKit = ( | |
|
||
const loggingConsole = fromEntries( | ||
arrayMap(consoleMethodPermits, ([name, _]) => { | ||
// Use an arrow function so that it doesn't come with its own name in | ||
// its printed form. Instead, we're hoping that tooling uses only | ||
// the `.name` property set below. | ||
/** | ||
* @param {...any} args | ||
*/ | ||
const method = (...args) => { | ||
const method = defineName(name, (...args) => { | ||
arrayPush(logArray, [name, ...args]); | ||
}; | ||
defineProperty(method, 'name', { value: name }); | ||
}); | ||
return [name, freeze(method)]; | ||
}), | ||
); | ||
|
@@ -370,7 +380,7 @@ export const makeCausalConsole = (baseConsole, loggedErrorHandler) => { | |
/** | ||
* @param {...any} logArgs | ||
*/ | ||
const levelMethod = (...logArgs) => { | ||
const levelMethod = defineName(level, (...logArgs) => { | ||
const subErrors = []; | ||
const argTags = extractErrorArgs(logArgs, subErrors); | ||
if (baseConsole[level]) { | ||
|
@@ -379,8 +389,7 @@ export const makeCausalConsole = (baseConsole, loggedErrorHandler) => { | |
} | ||
// @ts-expect-error ConsoleProp vs LogSeverity mismatch | ||
logSubErrors(level, subErrors); | ||
}; | ||
defineProperty(levelMethod, 'name', { value: level }); | ||
}); | ||
return [level, freeze(levelMethod)]; | ||
}); | ||
const otherMethodNames = arrayFilter( | ||
|
@@ -391,13 +400,12 @@ export const makeCausalConsole = (baseConsole, loggedErrorHandler) => { | |
/** | ||
* @param {...any} args | ||
*/ | ||
const otherMethod = (...args) => { | ||
const otherMethod = defineName(name, (...args) => { | ||
// @ts-ignore | ||
// eslint-disable-next-line @endo/no-polymorphic-call | ||
baseConsole[name](...args); | ||
return undefined; | ||
}; | ||
defineProperty(otherMethod, 'name', { value: name }); | ||
}); | ||
return [name, freeze(otherMethod)]; | ||
}); | ||
|
||
|
@@ -458,23 +466,21 @@ export const defineCausalConsoleFromLogger = loggedErrorHandler => { | |
} | ||
return tlogger(...args); | ||
}; | ||
const makeNamed = (name, fn) => | ||
({ [name]: (...args) => fn(...args) })[name]; | ||
|
||
const baseConsole = fromEntries([ | ||
...arrayMap(consoleLevelMethods, ([name]) => [ | ||
name, | ||
makeNamed(name, logWithIndent), | ||
defineName(name, (...args) => logWithIndent(...args)), | ||
]), | ||
...arrayMap(consoleOtherMethods, ([name]) => [ | ||
name, | ||
makeNamed(name, (...args) => logWithIndent(name, ...args)), | ||
defineName(name, (...args) => logWithIndent(name, ...args)), | ||
]), | ||
]); | ||
// https://console.spec.whatwg.org/#grouping | ||
for (const name of ['group', 'groupCollapsed']) { | ||
if (baseConsole[name]) { | ||
baseConsole[name] = makeNamed(name, (...args) => { | ||
baseConsole[name] = defineName(name, (...args) => { | ||
if (args.length >= 1) { | ||
// Prefix the logged data with "group" or "groupCollapsed". | ||
logWithIndent(...args); | ||
|
@@ -484,16 +490,17 @@ export const defineCausalConsoleFromLogger = loggedErrorHandler => { | |
arrayPush(indents, ' '); | ||
}); | ||
} else { | ||
baseConsole[name] = () => {}; | ||
baseConsole[name] = defineName(name, () => {}); | ||
} | ||
} | ||
if (baseConsole.groupEnd) { | ||
baseConsole.groupEnd = makeNamed('groupEnd', (...args) => { | ||
arrayPop(indents); | ||
}); | ||
} else { | ||
baseConsole.groupEnd = () => {}; | ||
} | ||
baseConsole.groupEnd = defineName( | ||
'groupEnd', | ||
baseConsole.groupEnd | ||
? (...args) => { | ||
arrayPop(indents); | ||
} | ||
: () => {}, | ||
); | ||
harden(baseConsole); | ||
const causalConsole = makeCausalConsole( | ||
/** @type {VirtualConsole} */ (baseConsole), | ||
|
@@ -518,14 +525,14 @@ export const filterConsole = (baseConsole, filter, _topic = undefined) => { | |
/** | ||
* @param {...any} args | ||
*/ | ||
const method = (...args) => { | ||
const method = defineName(name, (...args) => { | ||
// eslint-disable-next-line @endo/no-polymorphic-call | ||
if (severity === undefined || filter.canLog(severity)) { | ||
// @ts-ignore | ||
// eslint-disable-next-line @endo/no-polymorphic-call | ||
baseConsole[name](...args); | ||
} | ||
}; | ||
}); | ||
return [name, freeze(method)]; | ||
}); | ||
const filteringConsole = fromEntries(methods); | ||
|