Skip to content

fix(ci): stabilize mock server emit checks#5976

Closed
elrrrrrrr wants to merge 7 commits into
nextfrom
codex/pr-5969-ci
Closed

fix(ci): stabilize mock server emit checks#5976
elrrrrrrr wants to merge 7 commits into
nextfrom
codex/pr-5969-ci

Conversation

@elrrrrrrr

@elrrrrrrr elrrrrrrr commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • keep the original mock server-event fix, but emit the exact server returned by createServer() after app.ready() so there is no defensive uncovered branch
  • align the parallel mock app path with the single app path by running setCustomLoader(app) after config is available
  • pin @oclif/core to 4.11.4, matching the latest green next Windows bin run and avoiding the 4.11.7 fork timeout regression
  • add a narrow parallel wrapper regression fixture/test so Codecov patch covers the post-ready server emit path

CI investigation

  • Original failing PR run: Test bin (windows-latest, 24) timed out while forked egg-bin CLI child processes waited to exit, including --help/--version cases that do not boot an Egg app.
  • Failing run resolved @oclif/core@4.11.7; latest green next run used @oclif/core@4.11.4.
  • A prior PR attempt with floating Vitest but @oclif/core@4.11.4 had the Windows bin job green, while pinning Vitest alone did not fix the hang.
  • The broad packages/egg/src/lib/application.ts unittest/graceful workaround is removed from the final diff; it was not on the egg-bin --help/--version path and caused Codecov patch risk.

Local verification

  • utx utoo@1.0.32 install --from pnpm -> 8 workspaces, 1 overrides, 214 catalogs
  • dependency resolution confirmed locally: @oclif/core@4.11.4, rolldown-vite@7.3.1, vitest@4.1.9, @vitest/coverage-v8@4.1.9
  • utx utoo@1.0.32 run build -- --workspace ./tools/egg-bin
  • utx utoo@1.0.32 run ci --workspace @eggjs/bin
  • utx utoo@1.0.32 run test -- plugins/mock/test/app.test.ts
  • utx utoo@1.0.32 run typecheck --workspace @eggjs/mock

Remote verification

Draft PR #5976 is green on commit 1c6db712e3fec02ed27fd2e3d15dabfe3a19d499.

  • CI run 27836491515: passed, including Test bin (windows-latest, 24) in 3m23s and all normal test matrix jobs
  • E2E run 27836491493: passed (examples and cnpmcore)
  • CodeQL: passed
  • Codecov: codecov/patch passed and codecov/project passed
  • External checks: Cloudflare Pages, License Compliance, Socket Project Report, Snyk passed; Socket PR Alerts is neutral

elrrrrrrr and others added 6 commits June 18, 2026 19:18
@eggjs/mock created the http server and emitted the `server` event inside
`createServer()`, which runs BEFORE `app.ready()`. But egg core registers its
`once('server', server => this.onServer(server))` listener inside
`Application.load()` (during `app.ready()`), and `onServer` reads loaded config.
So the event was emitted before the listener existed (and before config was
loaded), and `onServer` — which wires up clientError logging, graceful shutdown,
server timeout and websocket support — never ran in single-process mock mode.

Move the `server` emit out of `createServer()` (it now only creates & caches the
server, so `app.server` stays available during boot as before) and emit it once
after `await app.ready()` in both the single and parallel app workers. This
mirrors @eggjs/cluster, which also emits `server` after the app is ready, and
keeps the event emitted exactly once.

Added a regression test asserting `app.server` has a `clientError` listener
after ready.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`onServer` now actually runs after the mock `server` re-emit, which wired up
`graceful()` in every app booted via `@eggjs/mock`. graceful installs a
process-wide `uncaughtException` handler that takes over process shutdown; in
egg-bin's per-test forked child processes this prevents a clean exit. On Windows
(no real POSIX signals, slower pipe/socket teardown) the child then hangs until
a kill timeout, so every `Test bin (windows)` case times out at 60s.

Skip graceful when `env === 'unittest'`; clientError logging and serverTimeout
still apply. graceful is a production resilience mechanism and is undesirable in
a test runner regardless.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The vitest 4.1.8 pin was an attempt to fix the Windows `Test bin` timeouts, but
the real cause was graceful running in unittest (fixed in the prior commit).
Restore the `^4.0.15` catalog range for vitest and @vitest/coverage-v8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This PR should not modify pnpm-workspace.yaml. Restore @oclif/core to ^4.2.0 so
the file matches next with no diff.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d3887b68-90b6-4a13-8918-32f0f537f473

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/pr-5969-ci

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@socket-security

socket-security Bot commented Jun 19, 2026

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request removes the environment check that skipped graceful shutdown handling during unit tests in Application.onServer, and pins the @oclif/core dependency version. Feedback is provided to add a defensive check in the graceful error handler to ensure the thrown error is a non-null object before accessing or modifying its properties, preventing potential runtime TypeErrors.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +156 to +170
error: (err: Error, throwErrorCount: number) => {
const originMessage = err.message;
if (originMessage) {
// shouldjs will override error property but only getter
// https://github.com/shouldjs/should.js/blob/889e22ebf19a06bc2747d24cf34b25cc00b37464/lib/assertion-error.js#L26
Object.defineProperty(err, 'message', {
get() {
return `${originMessage} (uncaughtException throw ${throwErrorCount} times on pid: ${process.pid})`;
},
configurable: true,
enumerable: false,
});
}
this.coreLogger.error(err);
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In JavaScript/TypeScript, any value (including primitives like strings, numbers, or null/undefined) can be thrown as an exception. If a non-object or null value is passed to the error callback, accessing err.message or calling Object.defineProperty(err, ...) will throw a runtime TypeError, crashing the uncaught exception handler itself. Adding a defensive check to ensure err is a non-null object before accessing its properties or modifying them prevents this secondary crash.

      error: (err: Error, throwErrorCount: number) => {
        if (err && typeof err === 'object') {
          const originMessage = err.message;
          if (originMessage) {
            // shouldjs will override error property but only getter
            // https://github.com/shouldjs/should.js/blob/889e22ebf19a06bc2747d24cf34b25cc00b37464/lib/assertion-error.js#L26
            Object.defineProperty(err, 'message', {
              get() {
                return `${originMessage} (uncaughtException throw ${throwErrorCount} times on pid: ${process.pid})`;
              },
              configurable: true,
              enumerable: false,
            });
          }
        }
        this.coreLogger.error(err);
      },

@elrrrrrrr elrrrrrrr changed the base branch from fix/mock-emit-server-after-ready to next June 19, 2026 15:30
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 19, 2026

Copy link
Copy Markdown

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1c6db71
Status: ✅  Deploy successful!
Preview URL: https://36984e1e.egg-v3.pages.dev
Branch Preview URL: https://codex-pr-5969-ci.egg-v3.pages.dev

View logs

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.82%. Comparing base (0333c73) to head (1c6db71).

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5976      +/-   ##
==========================================
+ Coverage   85.50%   85.82%   +0.31%     
==========================================
  Files         669      669              
  Lines       19825    19826       +1     
  Branches     3917     3917              
==========================================
+ Hits        16952    17016      +64     
+ Misses       2481     2428      -53     
+ Partials      392      382      -10     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 19, 2026

Copy link
Copy Markdown

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1c6db71
Status: ✅  Deploy successful!
Preview URL: https://d8986ef7.egg-cci.pages.dev
Branch Preview URL: https://codex-pr-5969-ci.egg-cci.pages.dev

View logs

@elrrrrrrr elrrrrrrr changed the title fix(ci): pin oclif core for egg-bin fix(ci): stabilize mock server emit checks Jun 19, 2026
@elrrrrrrr elrrrrrrr closed this Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant