refactor(server): clean up code review issues in plugin child TS conversion

- Remove `return false` from uncaughtException/unhandledRejection handlers (Node.js ignores it)
- Remove dead `RunPlugins.wrapChildPromise` method and its `UNDEFINED_SERIALIZED` constant (all call sites use the imported util function)
- Make `validateEvent` params `event` and `handler` required; remove unnecessary `!` assertion
- Fix `(val as Function).name` to use a typed object cast
- Collapse verbose 3-line comment in ProjectConfigIpc.ts to one line
- Remove trailing whitespace from tsconfig.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Bill Glesias
2026-05-20 20:56:21 -04:00
parent df70cd5259
commit a8581ce163
6 changed files with 7 additions and 38 deletions
@@ -20,10 +20,7 @@ const pkg = require('@packages/root')
const debug = debugLib(`cypress:lifecycle:ProjectConfigIpc`)
const debugVerbose = debugLib(`cypress-verbose:lifecycle:ProjectConfigIpc`)
// If in development, use the TypeScript require_async_child file
// Otherwise, the binary will be using the transpiled version of the Typescript file
// into whatever @packages/server JavaScript target is defined in the tsconfig.json
// In dev the .ts source exists; in production only the compiled .js is present.
const resolveRequireAsyncChildPath = (): string => {
const serverRoot = path.dirname(require.resolve('@packages/server/package.json'))
const tsPath = path.join(serverRoot, 'lib/plugins/child/require_async_child.ts')
@@ -33,7 +33,6 @@ const span = telemetry.startSpan({ name: 'child:process', active: true })
debug('child:process span initialized')
suppressWarnings()
// note: what is this doing?
gracefulify(fs)
const ipc = util.wrapIpc(process as unknown as util.WrappedIpcProcess)
@@ -24,8 +24,6 @@ import type {
const debug = debugLib(`cypress:lifecycle:child:RunPlugins:${process.pid}`)
const UNDEFINED_SERIALIZED = '__cypress_undefined__'
export class RunPlugins {
private ipc: PluginChildIpc
private projectRoot: string
@@ -186,27 +184,6 @@ export class RunPlugins {
return (event.handler as (...handlerArgs: any[]) => any)(...args)
}
wrapChildPromise (
invoke: (eventId: number, args?: any[]) => any,
ids: PluginInvokeIds,
args: any[] = [],
) {
return Promise.try(() => {
return invoke(ids.eventId, args)
})
.then((value) => {
// undefined is coerced into null when sent over ipc, but we need
// to differentiate between them for 'task' event
if (value === undefined) {
value = UNDEFINED_SERIALIZED
}
return this.ipc.send(`promise:fulfilled:${ids.invocationId}`, null, value)
}).catch((err) => {
return this.ipc.send(`promise:fulfilled:${ids.invocationId}`, serializeError(err))
})
}
taskGetBody (ids: PluginInvokeIds, args: any[]) {
const [event] = args
const taskEvent = _.find(this.registeredEventsById, { event: 'task' })
@@ -29,8 +29,6 @@ export function run (ipc: PluginChildIpc, file: string, projectRoot: string): vo
process.on('uncaughtException', (err) => {
debug('uncaught exception:', util.serializeError(err))
ipc.send('childProcess:unhandledError', util.serializeError(err))
return false
})
process.on('unhandledRejection', (event: BluebirdRejectionEvent | unknown) => {
@@ -45,8 +43,6 @@ export function run (ipc: PluginChildIpc, file: string, projectRoot: string): vo
}
ipc.send('childProcess:unhandledError', util.serializeError(err as Error))
return false
})
const isValidSetupNodeEvents = (config: ConfigFileExport, testingType: TestingType): boolean => {
@@ -142,7 +138,7 @@ export function run (ipc: PluginChildIpc, file: string, projectRoot: string): vo
const result = (configFileExport.default || configFileExport) as ConfigFileExport
const replacer = (_key: string, val: unknown) => {
return typeof val === 'function' ? `[Function ${(val as Function).name}]` : val
return typeof val === 'function' ? `[Function ${(val as { name: string }).name}]` : val
}
ipc.send('loadConfig:reply', { initialConfig: JSON.stringify(result, replacer), requires: util.nonNodeRequires() })
@@ -47,12 +47,12 @@ const eventValidators: Record<string, EventValidator> = {
}
export const validateEvent = (
event?: string,
handler?: unknown,
event: string,
handler: unknown,
config?: Cypress.PluginConfigOptions,
errConstructorFn?: () => void,
): ValidateEventResult => {
const validator = event ? eventValidators[event] : undefined
const validator = eventValidators[event]
if (!validator) {
const userEvents = _.reject(_.keys(eventValidators), (registeredEvent) => {
@@ -74,7 +74,7 @@ export const validateEvent = (
}
}
const result = validator(event!, handler, config)
const result = validator(event, handler, config)
if (!result.isValid) {
result.error.name = 'InvalidEventHandlerError'
+1 -1
View File
@@ -9,6 +9,6 @@
],
"compilerOptions": {
"lib": ["esnext"],
"target": "ES2022",
"target": "ES2022",
}
}