Skip to content

feat(onerror): merge @eggjs/onerror plugin into monorepo#5503

Merged
fengmk2 merged 6 commits intonextfrom
onerror
Sep 20, 2025
Merged

feat(onerror): merge @eggjs/onerror plugin into monorepo#5503
fengmk2 merged 6 commits intonextfrom
onerror

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented Sep 16, 2025

Move @eggjs/onerror plugin from separate repository to plugins/onerror. Configure for monorepo with workspace dependencies and standard tsdown build.

  • Add onerror plugin to plugins directory
  • Configure package.json with workspace and catalog dependencies
  • Add standard tsdown.config.ts following plugin conventions
  • Add vitest.config.ts for test configuration
  • Update root tsconfig.json references
  • Add cookie, koa-onerror, mustache, stack-trace to pnpm catalog
  • Add type definitions for mustache and stack-trace
  • Fix HTML syntax error in mustache template
  • Remove incorrectly created packages/egg/plugins/onerror directory

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Introduced the Onerror plugin: HTML/JSON/JSONP error responses, interactive syntax-highlighted error pages, production-safe messaging, redirect/custom template support, and agent-side error logging.
  • Documentation
    • Added README, CHANGELOG, and LICENSE for the Onerror plugin.
  • Chores
    • Updated TypeScript/package configs, workspace dependencies, build/test publishing metadata for the new plugin.
  • Tests
    • Added comprehensive test suite and fixtures covering multiple error scenarios, formats, and environments.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 16, 2025

Warning

Rate limit exceeded

@fengmk2 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 25 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 01f457a and 4983cb2.

📒 Files selected for processing (7)
  • packages/egg/test/lib/plugins/watcher.test.ts (1 hunks)
  • packages/mock/test/mock_service_cluster.test.ts (1 hunks)
  • plugins/development/test/development-ts.test.ts (1 hunks)
  • plugins/development/test/development.test.ts (1 hunks)
  • plugins/development/test/fast_ready_false.test.ts (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/template.mustache (1 hunks)
  • plugins/watcher/test/development_cluster.test.ts (1 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a new @eggjs/onerror plugin (source, config, templates, types, tests, packaging, docs). Migrates mock package typings from @eggjs/core to egg. Introduces package-level tsconfig baseUrl changes, updates tooling tsconfig inheritance, and adds workspace/catalog entries and a project reference for the new plugin.

Changes

Cohort / File(s) Summary
Onerror plugin — package, source, docs, tests
plugins/onerror/package.json, plugins/onerror/README.md, plugins/onerror/LICENSE, plugins/onerror/CHANGELOG.md, plugins/onerror/tsconfig.json, plugins/onerror/tsdown.config.ts, plugins/onerror/vitest.config.ts, plugins/onerror/src/index.ts, plugins/onerror/src/types.ts, plugins/onerror/src/app.ts, plugins/onerror/src/agent.ts, plugins/onerror/src/config/config.default.ts, plugins/onerror/src/lib/*, plugins/onerror/src/lib/onerror_page.mustache.html, plugins/onerror/test/*, plugins/onerror/test/fixtures/*
Adds a new onerror Egg plugin: lifecycle boots for app/agent, utilities, error view renderer and template, default config and types, build/test configs, docs, packaging fields, and extensive tests with fixtures.
Mock package — typing migration & package metadata
packages/mock/package.json, packages/mock/src/app.ts, packages/mock/src/app/extend/*, packages/mock/src/app/middleware/cluster_app_mock.ts, packages/mock/src/lib/context.ts, packages/mock/src/lib/parallel/*, packages/mock/src/lib/mock_agent.ts, packages/mock/test/*
Replaces @eggjs/core types with egg types (Application/Agent/Context), updates class/field/constructor signatures and related types; removes @eggjs/tsconfig devDependency and adds egg as a peerDependency; minor runtime/no-op behavior changes and added ts-expect-error annotations in tests; mock agent return typing and dispatcher wiring updated.
TypeScript per-package baseUrl changes
packages/koa/tsconfig.json, packages/supertest/tsconfig.json, packages/utils/tsconfig.json, plugins/onerror/tsconfig.json
Adds compilerOptions.baseUrl: "./" to enable non-relative imports from package roots; plugin tsconfig also adds excludes.
Tooling tsconfig inheritance change
tools/egg-bin/tsconfig.json
Changes extends to ../../tsconfig.json, removes several strict/emission overrides, retains baseUrl and excludes.
Workspace/catalog & root tsconfig
pnpm-workspace.yaml, tsconfig.json
Adds catalog dependencies (cookie, koa-onerror, mustache, stack-trace, typings) and adds ./plugins/onerror to root TS project references.
Tests & minor type suppressions across repo
packages/egg/test/**, packages/mock/test/*, packages/egg/test/*, other tests
Adds/updates test imports (e.g., .ts), inserts // @ts-expect-error in places with missing types, and changes some assertions to assert.equal.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant Koa as Koa App
  participant App as Egg Application
  participant OnErr as @eggjs/onerror
  participant Utils as onerror utils
  participant View as ErrorView/template

  Client->>Koa: HTTP request
  Koa->>App: execute route / middleware
  App-->>Koa: throws Error (err)
  Koa->>OnErr: onerror handler invoked (ctx, err)
  OnErr->>Utils: detectStatus(err) / accepts(ctx)
  alt accepts === html
    OnErr->>OnErr: maybe redirect via config.errorPageUrl
    OnErr->>View: render HTML via ErrorView
    View-->>OnErr: HTML body
    OnErr-->>Client: respond HTML (status)
  else accepts === json
    OnErr-->>Client: respond JSON body (code/message[/stack])
  else accepts === js/jsonp
    OnErr-->>Client: respond JSONP/JS via ctx.createJsonpBody
  end
Loading
sequenceDiagram
  autonumber
  participant Agent as Egg Agent
  participant Boot as onerror Agent Boot
  participant Logger as agent.coreLogger

  Agent->>Boot: new Boot(agent)
  Boot->>Agent: didLoad() registers agent.on('error', handler)
  Agent-->>Boot: emits 'error' (err)
  Boot->>Logger: coreLogger.error(err)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

In burrows of code I nibble lines,
I stitch stack traces into tiny signs.
I render pages, JSON clean and bright,
I chase the bugs that stir at night.
Hop—onerror fixed; the logs sleep light. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately summarizes the primary change: merging the @eggjs/onerror plugin into the monorepo. It uses a conventional commit style (feat(onerror): ...) and clearly reflects the added plugins/onerror package, configs, and tests so a reviewer scanning history can understand the main intent.

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.

@fengmk2 fengmk2 mentioned this pull request Sep 14, 2025
42 tasks
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Sep 16, 2025

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4983cb2
Status:🚫  Build failed.

View logs

@fengmk2 fengmk2 requested a review from Copilot September 16, 2025 15:47
Copy link
Contributor

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

Choose a reason for hiding this comment

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

Summary of Changes

Hello @fengmk2, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates the @eggjs/onerror plugin directly into the monorepo, streamlining its management and ensuring consistency with other internal packages. The migration involves updating its package.json for workspace compatibility, configuring tsdown for standardized builds, and setting up vitest for testing. Additionally, it includes minor fixes and enhancements to the error handling and display logic, ensuring a robust and well-integrated error reporting mechanism across the project.

Highlights

  • Monorepo Integration: The @eggjs/onerror plugin has been moved from a separate repository into the main monorepo, centralizing its development and maintenance.
  • Standardized Build & Dependencies: The plugin now uses workspace dependencies and a standard tsdown build configuration, aligning with the monorepo's conventions.
  • Updated Type Definitions & Testing: New type definitions for mustache and stack-trace have been added, and vitest is configured for testing the plugin.
  • Error Page Enhancements: The error page rendering logic has been refined, including a fix for an HTML syntax error in the Mustache template and improved handling of various error statuses and content types.
  • Dependency Catalog Updates: Several new dependencies, including cookie, koa-onerror, mustache, and stack-trace, have been added to the pnpm catalog.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR merges the standalone @eggjs/onerror plugin into the monorepo structure, bringing it in line with other plugins and providing standardized build tooling. The plugin handles error responses across different formats (HTML, JSON, JSONP) with production-safe error display.

  • Move @eggjs/onerror from separate repository to plugins/onerror directory
  • Standardize monorepo configuration with workspace dependencies and tsdown builds
  • Add required dependencies to pnpm catalog and fix HTML template syntax error

Reviewed Changes

Copilot reviewed 68 out of 70 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
plugins/onerror/* Complete onerror plugin with src/, test/, and config files
pnpm-workspace.yaml Add new dependencies: cookie, koa-onerror, mustache, stack-trace with types
tools/egg-bin/tsconfig.json Simplify tsconfig to extend from root configuration
packages/*/tsconfig.json Add baseUrl configuration for consistent path resolution
packages/mock/src/* Update imports from @eggjs/core to egg for better type alignment
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Sep 16, 2025

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4983cb2
Status:🚫  Build failed.

View logs

@socket-security
Copy link

socket-security bot commented Sep 16, 2025

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

Copy link
Contributor

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

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 successfully merges the @eggjs/onerror plugin into the monorepo. The changes are well-structured, including the addition of the new plugin, configuration updates, and refactoring of related packages. The inclusion of comprehensive tests is a great addition. I have identified a few areas for improvement concerning code conciseness, correctness, and performance, along with a syntax error in an HTML template. My detailed feedback is provided in the review comments.

@codecov
Copy link

codecov bot commented Sep 16, 2025

Codecov Report

❌ Patch coverage is 76.47059% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.31%. Comparing base (2dec12f) to head (4983cb2).
⚠️ Report is 5 commits behind head on next.

Files with missing lines Patch % Lines
packages/mock/src/app/extend/application.ts 86.95% 3 Missing ⚠️
packages/mock/src/lib/mock_agent.ts 62.50% 3 Missing ⚠️
packages/mock/src/lib/parallel/agent.ts 0.00% 1 Missing ⚠️
packages/mock/src/lib/parallel/app.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5503      +/-   ##
==========================================
- Coverage   76.34%   76.31%   -0.03%     
==========================================
  Files         113      113              
  Lines        5885     5891       +6     
  Branches     1233     1237       +4     
==========================================
+ Hits         4493     4496       +3     
- Misses       1215     1218       +3     
  Partials      177      177              

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
packages/mock/src/app/middleware/cluster_app_mock.ts (3)

15-16: Possible crash: args may be undefined (accessing length).

args can be absent; later args.length will throw. Normalize early and validate against the raw value.

-    const { method, property, args, needResult } = body;
+    const { method, property, args: rawArgs, needResult } = body ?? {};
+    const args: any[] = Array.isArray(rawArgs) ? [...rawArgs] : [];
@@
-    if (args && !Array.isArray(args)) {
+    if (rawArgs !== undefined && !Array.isArray(rawArgs)) {
       ctx.status = 422;
       ctx.body = {
         success: false,
         error: 'args should be an Array instance',
       };
       return;
     }
@@
-    for (let i = 0; i < args.length; i++) {
+    for (let i = 0; i < args.length; i++) {
       const arg = args[i];

Also applies to: 24-31, 71-90


95-101: Async handling bug: response may be set after middleware completes.

then() without await risks sending response before ctx.body is assigned and drops rejections. Await the call inside try/catch.

-      Promise.resolve(fn.call(target, ...args)).then(result => {
-        ctx.body = needResult ? { success: true, result } : { success: true };
-      });
+      const result = await Promise.resolve(fn.call(target, ...args));
+      ctx.body = needResult ? { success: true, result } : { success: true };
     } catch (err: any) {
       ctx.status = 500;
       ctx.body = { success: false, error: err.message };
     }

75-78: RCE surface via eval in request body. Gate to unittest only.

Evaluating arbitrary code from the request is dangerous if this middleware is reachable outside tests. Gate by env or remove in non‑test envs.

-          // eslint-disable-next-line
-          args[i] = eval(`(function() { return ${arg.value} })()`);
+          if (ctx.app.config.env === 'unittest') {
+            // eslint-disable-next-line no-eval
+            args[i] = eval(`(function() { return ${arg.value} })()`);
+          } else {
+            ctx.status = 403;
+            ctx.body = { success: false, error: 'mock function eval is disabled outside unittest env' };
+            return;
+          }
packages/mock/src/lib/parallel/agent.ts (2)

105-113: Preserve once() semantics during pre-init.

Using super.on inside once() can invoke the listener multiple times before binding. Use super.once.

Apply this diff:

-      super.on(args[0], args[1]);
+      super.once(args[0], args[1]);

1-132: Fix invalid typeof on type-only imports and pre-init once handler

  • Type-only typeof error — packages/mock/src/lib/parallel/agent.ts:55 and packages/mock/src/lib/parallel/app.ts:44: replace { Agent: typeof EggAgent } / { Application: typeof EggApplication } with { Agent: typeof import('egg').Agent } / { Application: typeof import('egg').Application } (or switch to value imports instead of import type).
  • once() cache bug — packages/mock/src/lib/parallel/agent.ts (≈lines 105–112): the pre-init once(...args) branch calls super.on(args[0], args[1]); change that to super.once(args[0], args[1]).
♻️ Duplicate comments (6)
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/user.js (1)

3-5: Same status parsing hardening as in onerror-4xx/user.js.

Replicate the integer parsing/validation to keep fixtures consistent.

Also applies to: 6-8

plugins/onerror/test/fixtures/onerror-customize/app/controller/user.js (1)

3-5: Mirror the status parsing fix here for consistency.

Keep all three user controllers aligned to reduce test flakiness on malformed input.

Also applies to: 6-8

plugins/onerror/test/fixtures/onerror-custom-template/template.mustache (1)

114-114: Fix malformed closing tag.

The tag is still </<div>; should be </div>.

-      </<div>
+      </div>
plugins/onerror/src/agent.ts (1)

6-8: Use constructor parameter property for brevity.

Same as prior feedback; keeps it concise without changing behavior.

-export default class Boot implements ILifecycleBoot {
-  private agent: Agent;
-
-  constructor(agent: Agent) {
-    this.agent = agent;
-  }
+export default class Boot implements ILifecycleBoot {
+  constructor(private readonly agent: Agent) {}
plugins/onerror/src/app.ts (1)

136-139: Preserve falsy values when merging error fields.

Using if (!errorJson[key]) skips valid falsy values (0, false, ''). Check key existence instead.

-            for (const key in err) {
-              if (!errorJson[key]) {
-                errorJson[key] = (err as any)[key];
-              }
-            }
+            for (const [key, value] of Object.entries(err as Record<string, any>)) {
+              if (!(key in errorJson)) {
+                errorJson[key] = value;
+              }
+            }
plugins/onerror/src/lib/error_view.ts (1)

274-276: Simplify check for dumpConfigToObject.

in is redundant with typeof guard.

-    if ('dumpConfigToObject' in this.app && typeof this.app.dumpConfigToObject === 'function') {
+    if (typeof this.app.dumpConfigToObject === 'function') {
🧹 Nitpick comments (46)
plugins/onerror/test/fixtures/onerror-custom-500/package.json (1)

1-3: Mark fixture as private to avoid accidental publish/workspace pickup.

Add "private": true to ensure this test fixture can’t be published or treated as a workspace package.

 {
-  "name": "onerror-custom-500"
+  "name": "onerror-custom-500",
+  "private": true
 }
plugins/onerror/test/fixtures/onerror-customize/package.json (1)

1-3: Set "private": true for test fixture packages.

Prevents accidental publishing and workspace linking.

 {
-  "name": "onerror-customize"
+  "name": "onerror-customize",
+  "private": true
 }
plugins/onerror/test/fixtures/onerror-4xx/package.json (1)

1-3: Make fixture package private.

Same rationale as other fixtures.

 {
-  "name": "onerror-4xx"
+  "name": "onerror-4xx",
+  "private": true
 }
plugins/onerror/test/fixtures/onerror-no-errorpage/package.json (1)

1-3: Mark as private.

Avoids accidental publish/workspace inclusion.

 {
-  "name": "onerror-no-errorpage"
+  "name": "onerror-no-errorpage",
+  "private": true
 }
plugins/onerror/test/fixtures/onerror-ctx-error/package.json (1)

1-3: Mark as private.

Same fixture hardening as others.

 {
-  "name": "onerror-ctx-error"
+  "name": "onerror-ctx-error",
+  "private": true
 }
plugins/onerror/test/fixtures/onerror-custom-template/package.json (1)

1-3: Mark as private.

Prevents accidental publication.

 {
-  "name": "onerror-customize-template"
+  "name": "onerror-customize-template",
+  "private": true
 }
plugins/onerror/tsconfig.json (1)

2-7: Confirm strict mode is effectively enabled.

If root tsconfig doesn’t set "strict": true, add it here to comply with repo-wide strict TS policy.

 {
   "extends": "../../tsconfig.json",
   "compilerOptions": {
-    "baseUrl": "./"
+    "baseUrl": "./",
+    "strict": true
   },
   "exclude": ["test/fixtures/**/*.ts", "dist/**/*"]
 }
packages/mock/src/app/middleware/cluster_app_mock.ts (2)

33-46: Harden property checks to avoid prototype exposure.

Use own‑property checks when reading ctx.app[property] to avoid __proto__/prototype leakage.

-      if (method === '__getter__') {
-        if (!ctx.app[property]) {
+      if (method === '__getter__') {
+        if (!Object.prototype.hasOwnProperty.call(ctx.app, property)) {
           debug('property %s not exists on app', property);
           ctx.status = 422;
           ctx.body = {
             success: false,
             error: `property "${property}" not exists on app`,
           };
           return;
         }
         ctx.body = { success: true, result: ctx.app[property] };
         return;
       }
@@
-      if (!ctx.app[property] || typeof (ctx.app as any)[property][method] !== 'function') {
+      if (!Object.prototype.hasOwnProperty.call(ctx.app, property) ||
+          typeof (ctx.app as any)[property][method] !== 'function') {
         debug('property %s.%s not exists on app', property, method);
         ctx.status = 422;
         ctx.body = {
           success: false,
           error: `method "${method}" not exists on app.${property}`,
         };
         return;
       }

Also applies to: 48-57


10-13: Optionally gate whole endpoint to unittest env.

If this middleware can be mounted in non‑test environments, short‑circuit early.

     if (ctx.originalUrl !== '/__egg_mock_call_function') {
       return next();
     }
+    if (ctx.app.config.env !== 'unittest') {
+      return next();
+    }
plugins/onerror/test/fixtures/onerror/package.json (1)

1-3: Mark test fixtures as private to prevent accidental publish.

Apply:

 {
   "name": "onerror",
+  "private": true
 }
plugins/onerror/test/fixtures/custom-listener-onerror/package.json (1)

1-3: Mark test fixtures as private to prevent accidental publish.

 {
   "name": "custom-listener-onerror",
+  "private": true
 }
plugins/onerror/test/fixtures/agent-error/package.json (1)

1-3: Mark test fixtures as private to prevent accidental publish.

 {
   "name": "agent-error",
+  "private": true
 }
packages/mock/src/app/extend/agent.ts (3)

13-14: Fix strictPropertyInitialization for _mockHttpClient.

Under strict mode this field is never assigned in constructor. Use definite assignment.

-  _mockHttpClient: MockHttpClientMethod;
+  _mockHttpClient!: MockHttpClientMethod;

15-19: Correct JSDoc receiver: should be Agent, not App.

Keeps docs consistent with the class name.

-   * @function App#mockHttpclient
+   * @function Agent#mockHttpclient

24-27: Correct JSDoc receiver on second method, too.

-   * @function App#mockHttpClient
+   * @function Agent#mockHttpClient
plugins/onerror/test/fixtures/onerror/app/controller/user.js (1)

6-9: Optionally parse JSON for errors param in tests.

Improves flexibility when passing errors as a JSON string.

-  if (ctx.query.errors) {
-    err.errors = ctx.query.errors;
-  }
+  if (ctx.query.errors) {
+    const q = ctx.query.errors;
+    if (typeof q === 'string') {
+      try { err.errors = JSON.parse(q); } catch { err.errors = q; }
+    } else {
+      err.errors = q;
+    }
+  }
plugins/onerror/test/fixtures/onerror-custom-template/app/controller/user.js (1)

6-9: Same optional parsing as above for consistency across fixtures.

-  if (ctx.query.errors) {
-    err.errors = ctx.query.errors;
-  }
+  if (ctx.query.errors) {
+    const q = ctx.query.errors;
+    if (typeof q === 'string') {
+      try { err.errors = JSON.parse(q); } catch { err.errors = q; }
+    } else {
+      err.errors = q;
+    }
+  }
plugins/onerror/test/fixtures/onerror-4xx/app/controller/user.js (1)

3-5: Guard status parsing to avoid NaN/float in err.status.

Use integer parsing with validation; current Number() could leave NaN or floats.

Apply:

-  if (ctx.query.status) {
-    err.status = Number(ctx.query.status);
-  }
+  if (ctx.query.status != null) {
+    const s = Number.parseInt(String(ctx.query.status), 10);
+    if (Number.isInteger(s)) err.status = s;
+  }

Also applies to: 6-8

plugins/onerror/test/fixtures/onerror-ctx-error/app/extend/context.js (1)

3-3: Nit: fix backtick in message (“can`t”) to an apostrophe or avoid contraction.

If tests assert the exact message, prefer “cannot” to dodge escaping.

-    throw new Error('you can`t get userId.');
+    throw new Error('you cannot get userId.');
plugins/onerror/test/fixtures/onerror-ctx-error/app/middleware/trigger.js (1)

4-6: Nit: typo and missing semicolon.

Purely cosmetic; fix “happend” → “happened” and add a semicolon.

-    ctx.logger.info('log something, then error happend.');
-    ctx.logger.info('%s', ctx.userId)
+    ctx.logger.info('log something, then error happened.');
+    ctx.logger.info('%s', ctx.userId);
plugins/onerror/test/fixtures/custom-listener-onerror/config/config.default.js (1)

5-7: Prefer ctx.logger for request-scoped logging.

Use ctx.logger to keep request context in logs.

-      ctx.app.logger.error('error happened');
+      ctx.logger.error('error happened');
plugins/onerror/CHANGELOG.md (1)

1-4: Silence markdownlint for imported historical changelog.

Keep upstream formatting; disable specific rules locally.

+<!-- markdownlint-disable MD003 MD034 MD036 MD007 -->
 # Changelog
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js (1)

6-8: Parse status robustly (avoid falsy '0' and NaN).

Guard Number() results; same for both handlers.

-  if (ctx.query.status) {
-    err.status = Number(ctx.query.status);
-  }
+  {
+    const status = Number(ctx.query.status);
+    if (!Number.isNaN(status)) err.status = status;
+  }

Apply in both places.

Also applies to: 22-24

plugins/onerror/test/fixtures/onerror-4xx/app/controller/home.js (1)

6-8: Same status parsing nit as the other fixture.

Use a NaN check to avoid accidental coercion/falsy pitfalls.

-  if (ctx.query.status) {
-    err.status = Number(ctx.query.status);
-  }
+  {
+    const status = Number(ctx.query.status);
+    if (!Number.isNaN(status)) err.status = status;
+  }

Also applies to: 22-24

plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js (1)

6-8: Guard against NaN and invalid HTTP status when parsing from query.

Number(ctx.query.status) can yield NaN; prefer a finite integer check.

-  if (ctx.query.status) {
-    err.status = Number(ctx.query.status);
-  }
+  if (ctx.query.status != null) {
+    const s = Number.parseInt(String(ctx.query.status), 10);
+    if (Number.isFinite(s)) err.status = s;
+  }
plugins/onerror/src/lib/utils.ts (2)

6-9: Pass content types to ctx.request.is as an array to avoid TS/overload ambiguity.

This also keeps parity with type-is’ array form.

-      ctx.request.is('application/json', 'application/vnd.api+json', 'application/csp-report')) {
+      ctx.request.is([
+        'application/json',
+        'application/vnd.api+json',
+        'application/csp-report',
+      ])) {

24-28: Explicitly type the return union of accepts().

Minor clarity win for downstream call sites.

-export function accepts(ctx: Context) {
+export function accepts(ctx: Context): 'json' | 'js' | 'html' {
packages/mock/src/app/extend/application.ts (1)

249-251: Use boolean for “secure” on the mocked request.

Current value is a string; make it a boolean to match expectations.

-      secure: 'false',
+      secure: false,
plugins/onerror/test/fixtures/onerror/app/controller/home.js (1)

16-18: Defensive: err.stack may be undefined.

Avoid TypeError when Error lacks a stack in some runtimes.

-  err.stack = err.stack.replace(/(controller\/home\.)js/, '$1ts');
+  if (err.stack) {
+    err.stack = err.stack.replace(/(controller\/home\.)js/, '$1ts');
+  }
plugins/onerror/test/fixtures/onerror-custom-template/template.mustache (1)

16-16: Optional: add alt text to the decorative image.

Improves a11y.

-      <img class="error-logo" src="https://zos.alipayobjects.com/rmsportal/JFKAMfmPehWfhBPdCjrw.svg"/>
+      <img class="error-logo" alt="" src="https://zos.alipayobjects.com/rmsportal/JFKAMfmPehWfhBPdCjrw.svg"/>
plugins/onerror/src/lib/onerror_page.mustache.html (2)

5-5: Optional: populate the document title.

Small UX improvement for browser tabs.

-  <title></title>
+  <title>{{ status }} {{ name }} — {{ request.url }}</title>

581-581: Optional: add alt text to the logo image.

-      <img class="error-logo" src="https://zos.alipayobjects.com/rmsportal/JFKAMfmPehWfhBPdCjrw.svg"/>
+      <img class="error-logo" alt="" src="https://zos.alipayobjects.com/rmsportal/JFKAMfmPehWfhBPdCjrw.svg"/>
plugins/onerror/package.json (2)

4-16: Expose .d.ts for all subpath exports via publishConfig.exports.

TypeScript won’t pick up declarations for subpaths (e.g., ./lib/utils) unless you add a "types" mapping per export (or typesVersions). Recommend switching string targets to objects with "types" + "default".

Apply this diff:

   "publishConfig": {
     "access": "public",
-    "exports": {
-      ".": "./dist/index.js",
-      "./agent": "./dist/agent.js",
-      "./app": "./dist/app.js",
-      "./config/config.default": "./dist/config/config.default.js",
-      "./lib/error_view": "./dist/lib/error_view.js",
-      "./lib/utils": "./dist/lib/utils.js",
-      "./types": "./dist/types.js",
-      "./package.json": "./package.json"
-    }
+    "exports": {
+      ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
+      "./agent": { "types": "./dist/agent.d.ts", "default": "./dist/agent.js" },
+      "./app": { "types": "./dist/app.d.ts", "default": "./dist/app.js" },
+      "./config/config.default": {
+        "types": "./dist/config/config.default.d.ts",
+        "default": "./dist/config/config.default.js"
+      },
+      "./lib/error_view": {
+        "types": "./dist/lib/error_view.d.ts",
+        "default": "./dist/lib/error_view.js"
+      },
+      "./lib/utils": {
+        "types": "./dist/lib/utils.d.ts",
+        "default": "./dist/lib/utils.js"
+      },
+      "./types": { "types": "./dist/types.d.ts", "default": "./dist/types.js" },
+      "./package.json": "./package.json"
+    }
   },

24-28: Homepage branch pin.

Linking to tree/master can drift; prefer HEAD to follow the default branch automatically.

-  "homepage": "https://github.com/eggjs/egg/tree/master/plugins/onerror#readme",
+  "homepage": "https://github.com/eggjs/egg/tree/HEAD/plugins/onerror#readme",
plugins/onerror/test/fixtures/agent-error/agent.js (1)

1-6: Speed up/flakiness: avoid 500ms sleep in tests.

Use setImmediate or a tiny timeout to reduce test time and flakes.

-  setTimeout(() => {
+  setImmediate(() => {
     done(new Error('emit error'));
-  }, 500);
+  });
plugins/onerror/src/types.ts (1)

1-6: Tighten re-export.

Inline the type re-export and drop the separate import.

-import type {
-  OnerrorConfig,
-} from './config/config.default.ts';
-
-export type { OnerrorConfig };
+export type { OnerrorConfig } from './config/config.default.ts';
plugins/onerror/src/app.ts (1)

26-27: Guard template loading for resilience.

If the template path is missing or unreadable, readFileSync will fail at boot. Consider try/catch with a minimal fallback template to avoid crashing startup.

-    const viewTemplate = fs.readFileSync(config.templatePath, 'utf8');
+    let viewTemplate = '';
+    try {
+      viewTemplate = fs.readFileSync(config.templatePath, 'utf8');
+    } catch (e) {
+      this.app.logger.warn('[onerror] failed to read template: %s', e);
+      viewTemplate = '<h1>Internal Server Error</h1>';
+    }
plugins/onerror/test/onerror.test.ts (3)

115-119: Fix typo in test title.

Minor spelling nit: “accpets” → “accepts”.

-  it('should support custom accpets return err.stack', () => {
+  it('should support custom accepts return err.stack', () => {

324-326: Remove duplicate assignment.

app = app = mm.app(...) assigns twice.

-      app = app = mm.app({
+      app = mm.app({

344-346: Remove duplicate assignment (second occurrence).

-      app = app = mm.app({
+      app = mm.app({
plugins/onerror/src/lib/error_view.ts (5)

15-15: Anchor the “starting slash” regex.

Current /\\|\\// removes the first slash anywhere, not just at the start. Anchor to start to address CodeQL warning and intent.

-const startingSlashRegex = /\\|\//;
+const startingSlashRegex = /^(?:[\\/]+)/;

201-205: Prefer removing only leading CWD and normalize consistently.

With the anchored regex above, this will reliably trim leading separators after stripping process.cwd().


127-142: Guard against missing filenames and avoid sync I/O on hot path.

  • If frame.getFileName() returns falsy, existsSync/readFileSync can throw.
  • Synchronous I/O can block even in local env with large stacks.
-  getFrameSource(frame: StackFrame): FrameSource {
-    const filename = frame.getFileName();
+  getFrameSource(frame: StackFrame): FrameSource {
+    const filename = frame.getFileName();
+    if (!filename) {
+      return { pre: [], line: '', post: [] };
+    }
     const lineNumber = frame.getLineNumber();
     let contents = this.getAssets(filename);
     if (!contents) {
       contents = fs.existsSync(filename) ? fs.readFileSync(filename, 'utf8') : '';
       this.setAssets(filename, contents);
     }

Optional follow‑up (non‑blocking): make toHTML/parseError/getFrameSource async and use fs.promises.readFile, keeping a small LRU cache.


244-252: Redact additional sensitive headers.

Consider expanding _filterHeaders to avoid leaking secrets on dev error pages (authorization tokens, API keys, CSRF tokens).

-  _filterHeaders = [ 'cookie', 'connection' ];
+  _filterHeaders = [
+    'cookie',
+    'connection',
+    'authorization',
+    'proxy-authorization',
+    'x-api-key',
+    'x-csrf-token',
+    'x-xsrf-token',
+    'x-egg-session',
+  ];

Also applies to: 35-37


223-236: Use Array.isArray for robustness.

Minor readability/semantics improvement.

-      frames: stack instanceof Array ? stack.filter(frame => frame.getFileName()).map(frameFormatter) : [],
+      frames: Array.isArray(stack) ? stack.filter(frame => frame.getFileName()).map(frameFormatter) : [],
packages/mock/src/lib/parallel/agent.ts (1)

79-91: Clear cached listener sets after binding to avoid leaks.

After migrating listeners to the agent, clear the caches.

Apply this diff:

   #bindEvents() {
@@
     for (const args of this.#initOnceListeners) {
       debug('once(%s), use cache and pass to agent', args);
       this._instance.once(args[0], args[1]);
       this.removeListener(args[0], args[1]);
     }
+    this.#initOnListeners.clear();
+    this.#initOnceListeners.clear();
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8014c66 and fbfbce8.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (69)
  • packages/koa/tsconfig.json (1 hunks)
  • packages/mock/package.json (1 hunks)
  • packages/mock/src/app.ts (1 hunks)
  • packages/mock/src/app/extend/agent.ts (2 hunks)
  • packages/mock/src/app/extend/application.ts (2 hunks)
  • packages/mock/src/app/middleware/cluster_app_mock.ts (1 hunks)
  • packages/mock/src/lib/context.ts (0 hunks)
  • packages/mock/src/lib/parallel/agent.ts (3 hunks)
  • packages/mock/src/lib/parallel/app.ts (3 hunks)
  • packages/supertest/tsconfig.json (1 hunks)
  • packages/utils/tsconfig.json (1 hunks)
  • plugins/onerror/CHANGELOG.md (1 hunks)
  • plugins/onerror/LICENSE (1 hunks)
  • plugins/onerror/README.md (1 hunks)
  • plugins/onerror/package.json (1 hunks)
  • plugins/onerror/src/agent.ts (1 hunks)
  • plugins/onerror/src/app.ts (1 hunks)
  • plugins/onerror/src/config/config.default.ts (1 hunks)
  • plugins/onerror/src/index.ts (1 hunks)
  • plugins/onerror/src/lib/error_view.ts (1 hunks)
  • plugins/onerror/src/lib/onerror_page.mustache.html (1 hunks)
  • plugins/onerror/src/lib/utils.ts (1 hunks)
  • plugins/onerror/src/types.ts (1 hunks)
  • plugins/onerror/test/fixtures/agent-error/agent.js (1 hunks)
  • plugins/onerror/test/fixtures/agent-error/package.json (1 hunks)
  • plugins/onerror/test/fixtures/custom-listener-onerror/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/custom-listener-onerror/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/custom-listener-onerror/package.json (1 hunks)
  • plugins/onerror/test/fixtures/mock-test-error/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/app/extend/context.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/app/middleware/trigger.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-500/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-500/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-500/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/template.mustache (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/package.json (1 hunks)
  • plugins/onerror/test/onerror.test.ts (1 hunks)
  • plugins/onerror/tsconfig.json (1 hunks)
  • plugins/onerror/tsdown.config.ts (1 hunks)
  • plugins/onerror/vitest.config.ts (1 hunks)
  • pnpm-workspace.yaml (4 hunks)
  • tools/egg-bin/tsconfig.json (1 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/mock/src/lib/context.ts
🧰 Additional context used
📓 Path-based instructions (13)
{packages,plugins,tools}/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/package.json: Individual packages must reference external dependencies via "catalog:" from pnpm-workspace.yaml
Use "workspace:*" for internal monorepo dependencies between packages

Files:

  • plugins/onerror/test/fixtures/onerror-custom-500/package.json
  • plugins/onerror/test/fixtures/mock-test-error/package.json
  • plugins/onerror/test/fixtures/agent-error/package.json
  • plugins/onerror/test/fixtures/onerror/package.json
  • plugins/onerror/test/fixtures/onerror-customize/package.json
  • plugins/onerror/test/fixtures/onerror-ctx-error/package.json
  • plugins/onerror/test/fixtures/onerror-custom-template/package.json
  • packages/mock/package.json
  • plugins/onerror/test/fixtures/onerror-no-errorpage/package.json
  • plugins/onerror/test/fixtures/onerror-4xx/package.json
  • plugins/onerror/test/fixtures/custom-listener-onerror/package.json
  • plugins/onerror/package.json
packages/*/tsconfig.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"

Files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • packages/utils/tsconfig.json
{tsconfig.json,packages/*/tsconfig.json}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Enable strict TypeScript mode across all packages

Files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • packages/utils/tsconfig.json
  • tsconfig.json
{packages,plugins,tools}/**/tsconfig.json

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/tsconfig.json: All sub-project tsconfig.json files must extend the root tsconfig.json using "extends": "../../tsconfig.json"
All sub-project tsconfig.json files must include compilerOptions.baseUrl set to "./"

Files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use TypeScript for all source files in packages (no JavaScript source files)

Files:

  • packages/mock/src/app/extend/agent.ts
  • packages/mock/src/app/middleware/cluster_app_mock.ts
  • packages/mock/src/lib/parallel/app.ts
  • packages/mock/src/app.ts
  • packages/mock/src/lib/parallel/agent.ts
  • packages/mock/src/app/extend/application.ts
packages/*/package.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use "workspace:*" for internal workspace dependencies in package.json

Files:

  • packages/mock/package.json
{packages,plugins}/**/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins}/**/test/**/*.test.ts: Vitest test files should follow the naming pattern test/**/*.test.ts and import from vitest
Use Node.js built-in assert for assertions in Vitest tests

Files:

  • plugins/onerror/test/onerror.test.ts
pnpm-workspace.yaml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Define external dependency versions centrally in the catalog section of pnpm-workspace.yaml

Files:

  • pnpm-workspace.yaml
plugins/**/tsdown.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

All plugins must use the standard tsdown configuration template (entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true)

Files:

  • plugins/onerror/tsdown.config.ts
{packages,plugins,tools}/**/tsdown.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each package must use tsdown for unbundled ESM builds with type declarations (unbundle: true, dts: true)

Files:

  • plugins/onerror/tsdown.config.ts
{packages,plugins}/**/vitest.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each non-CLI package must include a vitest.config.ts for test configuration

Files:

  • plugins/onerror/vitest.config.ts
tsconfig.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Root tsconfig.json must include all packages in the references array

Files:

  • tsconfig.json
plugins/*/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

plugins/*/package.json: Plugin package.json must export TS sources in development ("exports": { ".": "./src/index.ts", "./agent": "./src/agent.ts", "./app": "./src/app.ts", "./package.json": "./package.json" })
Plugin package.json must mirror exports for publish via publishConfig.exports pointing to compiled JS in dist (e.g., "./dist/index.js")
Plugin package.json must include "files": ["dist"]
Plugin package.json must include scripts: build (tsdown), clean (rimraf dist), prepublishOnly (npm run build)
Plugin package.json must include an eggPlugin configuration field

Files:

  • plugins/onerror/package.json
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to packages/egg/tsconfig.json : packages/egg/tsconfig.json must extend eggjs/tsconfig and enable strict mode
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to packages/egg/tsdown.config.ts : packages/egg must use tsdown configured for unbundled ESM output
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must include an eggPlugin configuration field
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins,tools}/**/tsconfig.json : All sub-project tsconfig.json files must include compilerOptions.baseUrl set to "./"

Applied to files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsconfig.json : All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"

Applied to files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins,tools}/**/tsconfig.json : All sub-project tsconfig.json files must extend the root tsconfig.json using "extends": "../../tsconfig.json"

Applied to files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to packages/egg/tsconfig.json : packages/egg/tsconfig.json must extend eggjs/tsconfig and enable strict mode

Applied to files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must export TS sources in development ("exports": { ".": "./src/index.ts", "./agent": "./src/agent.ts", "./app": "./src/app.ts", "./package.json": "./package.json" })

Applied to files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
  • plugins/onerror/tsdown.config.ts
  • plugins/onerror/package.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/**/tsdown.config.ts : All plugins must use the standard tsdown configuration template (entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true)

Applied to files:

  • packages/koa/tsconfig.json
  • packages/supertest/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
  • plugins/onerror/tsdown.config.ts
  • tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to tools/egg-bin/tsdown.config.ts : egg-bin tool must use tsdown for TypeScript compilation

Applied to files:

  • tools/egg-bin/tsconfig.json
  • plugins/onerror/tsdown.config.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to packages/egg/tsdown.config.ts : packages/egg must use tsdown configured for unbundled ESM output

Applied to files:

  • tools/egg-bin/tsconfig.json
  • plugins/onerror/tsdown.config.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin (CLI tool) tests must use Mocha

Applied to files:

  • tools/egg-bin/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to {tsconfig.json,packages/*/tsconfig.json} : Enable strict TypeScript mode across all packages

Applied to files:

  • tools/egg-bin/tsconfig.json
  • packages/utils/tsconfig.json
  • plugins/onerror/tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins,tools}/**/tsdown.config.ts : Each package must use tsdown for unbundled ESM builds with type declarations (unbundle: true, dts: true)

Applied to files:

  • tools/egg-bin/tsconfig.json
  • plugins/onerror/tsconfig.json
  • plugins/onerror/tsdown.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsdown.config.ts : Each package must provide a tsdown.config.ts for unbundled ESM builds

Applied to files:

  • tools/egg-bin/tsconfig.json
  • plugins/onerror/tsconfig.json
  • plugins/onerror/tsdown.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/package.json : Use "workspace:*" for internal workspace dependencies in package.json

Applied to files:

  • packages/mock/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to pnpm-workspace.yaml : Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Applied to files:

  • packages/mock/package.json
  • pnpm-workspace.yaml
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to pnpm-workspace.yaml : Define external dependency versions centrally in the catalog section of pnpm-workspace.yaml

Applied to files:

  • packages/mock/package.json
  • pnpm-workspace.yaml
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins,tools}/**/package.json : Individual packages must reference external dependencies via "catalog:" from pnpm-workspace.yaml

Applied to files:

  • packages/mock/package.json
  • pnpm-workspace.yaml
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins}/**/vitest.config.ts : Each non-CLI package must include a vitest.config.ts for test configuration

Applied to files:

  • plugins/onerror/vitest.config.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins}/**/test/**/*.test.ts : Vitest test files should follow the naming pattern test/**/*.test.ts and import from vitest

Applied to files:

  • plugins/onerror/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • plugins/onerror/vitest.config.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must mirror exports for publish via publishConfig.exports pointing to compiled JS in dist (e.g., "./dist/index.js")

Applied to files:

  • plugins/onerror/package.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must include an eggPlugin configuration field

Applied to files:

  • plugins/onerror/package.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must include scripts: build (tsdown), clean (rimraf dist), prepublishOnly (npm run build)

Applied to files:

  • plugins/onerror/package.json
🧬 Code graph analysis (19)
plugins/onerror/test/fixtures/onerror-customize/config/config.default.js (2)
plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror-customize/app/controller/user.js (1)
  • err (2-2)
plugins/onerror/test/fixtures/onerror-customize/app/controller/user.js (1)
plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/src/lib/utils.ts (5)
plugins/onerror/test/fixtures/onerror-4xx/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror-custom-template/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror/app/controller/home.js (3)
  • err (2-2)
  • err (16-16)
  • err (27-27)
plugins/onerror/src/config/config.default.ts (2)
plugins/onerror/src/types.ts (1)
  • OnerrorConfig (5-5)
plugins/onerror/test/fixtures/onerror-custom-template/config/config.default.js (1)
  • path (1-1)
packages/mock/src/app/extend/agent.ts (1)
packages/egg/src/index.ts (1)
  • Agent (60-60)
plugins/onerror/src/agent.ts (2)
plugins/onerror/src/app.ts (1)
  • Boot (17-165)
packages/egg/src/lib/core/base_hook_class.ts (1)
  • agent (31-37)
plugins/onerror/test/fixtures/onerror-custom-template/app/controller/home.js (1)
plugins/onerror/test/fixtures/onerror/app/controller/home.js (3)
  • err (2-2)
  • err (16-16)
  • err (27-27)
packages/mock/src/lib/parallel/app.ts (1)
packages/utils/src/import.ts (1)
  • importModule (450-522)
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js (2)
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/user.js (1)
  • err (2-2)
plugins/onerror/test/fixtures/onerror/app/controller/home.js (3)
  • err (2-2)
  • err (16-16)
  • err (27-27)
plugins/onerror/test/onerror.test.ts (3)
packages/mock/test/helper.ts (1)
  • getFixtures (5-7)
packages/mock/src/register.ts (3)
  • beforeAll (22-28)
  • afterAll (37-45)
  • afterEach (29-36)
packages/mock/src/app/extend/application.ts (1)
  • mm (366-368)
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/user.js (1)
plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror-custom-template/app/controller/user.js (1)
plugins/onerror/test/fixtures/onerror-custom-template/app/controller/home.js (2)
  • err (2-2)
  • err (21-21)
plugins/onerror/test/fixtures/onerror/app/controller/user.js (2)
plugins/onerror/test/fixtures/onerror-4xx/app/controller/user.js (1)
  • err (2-2)
plugins/onerror/test/fixtures/onerror/app/controller/home.js (3)
  • err (2-2)
  • err (16-16)
  • err (27-27)
packages/mock/src/app.ts (2)
plugins/onerror/src/agent.ts (1)
  • Boot (3-16)
plugins/onerror/src/app.ts (1)
  • Boot (17-165)
plugins/onerror/src/types.ts (2)
packages/egg/src/lib/types.ts (1)
  • EggAppConfig (97-271)
plugins/onerror/src/config/config.default.ts (1)
  • OnerrorConfig (6-26)
packages/mock/src/lib/parallel/agent.ts (1)
packages/utils/src/import.ts (1)
  • importModule (450-522)
packages/mock/src/app/extend/application.ts (3)
packages/mock/src/index.ts (1)
  • ApplicationUnittest (97-97)
packages/egg/src/index.ts (1)
  • Application (54-54)
packages/mock/src/lib/types.ts (1)
  • MockOptions (1-50)
plugins/onerror/src/lib/error_view.ts (1)
plugins/onerror/src/lib/utils.ts (1)
  • detectErrorMessage (4-12)
plugins/onerror/src/app.ts (3)
plugins/onerror/src/lib/utils.ts (4)
  • detectStatus (14-22)
  • accepts (24-28)
  • isProd (30-32)
  • detectErrorMessage (4-12)
plugins/onerror/src/lib/error_view.ts (1)
  • ErrorView (27-282)
plugins/onerror/src/config/config.default.ts (1)
  • OnerrorConfig (6-26)
🪛 markdownlint-cli2 (0.17.2)
plugins/onerror/CHANGELOG.md

13-13: Bare URL used

(MD034, no-bare-urls)


15-15: Bare URL used

(MD034, no-bare-urls)


42-42: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


45-45: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


46-46: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


48-48: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


51-51: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


52-52: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


54-54: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


55-55: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


56-56: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


58-58: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


61-61: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


62-62: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


64-64: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


67-67: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


68-68: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


70-70: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


73-73: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


74-74: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


75-75: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


77-77: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


78-78: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


79-79: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


81-81: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


84-84: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


86-86: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


89-89: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


91-91: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


94-94: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


96-96: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


99-99: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


100-100: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


102-102: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


105-105: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


107-107: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


110-110: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


112-112: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


115-115: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


117-117: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


120-120: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


122-122: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


125-125: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


127-127: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


130-130: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


132-132: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


135-135: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


137-137: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


140-140: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


141-141: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


143-143: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


146-146: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


148-148: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


151-151: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


152-152: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


154-154: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


157-157: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


159-159: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


161-161: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

🪛 GitHub Check: CodeQL
plugins/onerror/src/lib/onerror_page.mustache.html

[warning] 740-740: DOM text reinterpreted as HTML
DOM text is reinterpreted as HTML without escaping meta-characters.


[warning] 741-741: DOM text reinterpreted as HTML
DOM text is reinterpreted as HTML without escaping meta-characters.
DOM text is reinterpreted as HTML without escaping meta-characters.

plugins/onerror/src/lib/error_view.ts

[failure] 202-202: Incomplete string escaping or encoding
This replaces only the first occurrence of /\|//.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Test egg-bin (macos-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 24)
  • GitHub Check: Test egg-bin (windows-latest, 24)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (macos-latest, 24)
  • GitHub Check: Test packages (windows-latest, 24)
  • GitHub Check: Test packages (windows-latest, 22)
  • GitHub Check: Test packages (ubuntu-latest, 22)
  • GitHub Check: Test packages (macos-latest, 24)
  • GitHub Check: Test packages (macos-latest, 22)
  • GitHub Check: Test packages (ubuntu-latest, 24)

fengmk2 and others added 3 commits September 20, 2025 18:51
Move @eggjs/onerror plugin from separate repository to plugins/onerror.
Configure for monorepo with workspace dependencies and standard tsdown build.

- Add onerror plugin to plugins directory
- Configure package.json with workspace and catalog dependencies
- Add standard tsdown.config.ts following plugin conventions
- Add vitest.config.ts for test configuration
- Update root tsconfig.json references
- Add cookie, koa-onerror, mustache, stack-trace to pnpm catalog
- Add type definitions for mustache and stack-trace
- Fix HTML syntax error in mustache template
- Remove incorrectly created packages/egg/plugins/onerror directory

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (5)
plugins/onerror/test/fixtures/onerror-custom-template/template.mustache (2)

114-114: Fix malformed HTML closing tag.

There's a malformed closing tag </<div> that will cause invalid HTML output.

-      </<div>
+      </div>

153-170: Security: Avoid implicit globals and use textContent instead of innerHTML for safer DOM manipulation.

The code creates $frameContext without proper declaration and uses .innerHTML which can lead to XSS vulnerabilities when handling user-controlled error data. Use textContent for safer rendering.

-          $frameContext = frame.querySelector('.frame-context');
-          var $context = $frameContext.innerHTML;
+          const $frameContext = frame.querySelector('.frame-context');
+          let $context = $frameContext.textContent || '';
           $context = $context.trim().length === 0 ? 'Missing stack frames' : $context;
           var $line = $frameContext.getAttribute('data-line');
           var $start = $frameContext.getAttribute('data-start');
           var $file = $frameContext.getAttribute('data-file');
           var $method = $frameContext.getAttribute('data-method');
           var $lineColumn = $frameContext.getAttribute('data-line-column');
           var $language = $frameContext.getAttribute('data-extname') || 'js';
           $('#code-drop').parentNode.setAttribute('data-line', $line);
           $('#code-drop').parentNode.setAttribute('data-start', $start);
           $('#code-drop').parentNode.setAttribute('data-language', $language);
           $('#code-drop').parentNode.setAttribute('data-line-offset', (Number($start) - 1));
           $('#code-drop').setAttribute('class', 'language-' + $language);
-          $('#code-drop').innerHTML = $context;
-          $('#frame-file').innerHTML = $file;
-          $('#frame-method').innerHTML = $method + '' + $lineColumn;
+          $('#code-drop').textContent = $context;
+          $('#frame-file').textContent = $file;
+          $('#frame-method').textContent = $method + '' + $lineColumn;
plugins/onerror/src/app.ts (1)

136-139: Don’t overwrite falsy error fields; check presence instead.

Use an existence check so 0, false, or '' aren’t clobbered.

-            for (const key in err) {
-              if (!errorJson[key]) {
-                errorJson[key] = (err as any)[key];
-              }
-            }
+            for (const key in err) {
+              if (!(key in errorJson)) {
+                errorJson[key] = (err as any)[key];
+              }
+            }
plugins/onerror/src/lib/error_view.ts (2)

274-276: Simplify the function check.

in is redundant here.

-    if ('dumpConfigToObject' in this.app && typeof this.app.dumpConfigToObject === 'function') {
+    if (typeof this.app.dumpConfigToObject === 'function') {

127-142: Optional: make source loading async to avoid sync I/O in request path.

Converting getFrameSource, parseError, and toHTML to async with fs.promises will prevent event‑loop blocking when rendering the dev HTML page.

Also applies to: 147-155, 52-65

🧹 Nitpick comments (27)
plugins/onerror/test/fixtures/custom-listener-onerror/app/router.js (1)

4-4: Nit: consider nullish coalescing to avoid treating empty string as “missing”.

Only if you want ?name= to keep an empty name instead of defaulting to "Error".

-    err.name = ctx.query.name || 'Error';
+    err.name = ctx.query?.name ?? 'Error';
packages/egg/test/cluster1/cluster-client.test.ts (2)

19-21: Prefer a narrow cast over @ts-expect-error for symbol-indexed access

Using @ts-expect-error makes the test brittle if types are later added. A targeted cast avoids disabling the checker and keeps runtime identical.

-      // @ts-expect-error registryClient no type definition
-      const agentInnerClient = app.agent.registryClient[innerClient];
+      const agentInnerClient =
+        (app.agent.registryClient as any)[innerClient] as {
+          _realClient: { closed: boolean };
+        };
-      // @ts-expect-error registryClient no type definition
-      const agentInnerClient = app.agent.registryClient[innerClient];
+      const agentInnerClient =
+        (app.agent.registryClient as any)[innerClient] as {
+          _realClient: { closed: boolean };
+        };

Also applies to: 61-63


22-22: Unify mm.restore usage (await vs non‑await)

First block awaits mm.restore(), second does not. Make them consistent to avoid subtle teardown ordering issues.

-      mm.restore();
+      await mm.restore();

Please confirm whether mm.restore() is sync or async in @eggjs/mock; awaiting a sync function is harmless, but consistency helps.

Also applies to: 64-64

packages/egg/test/app/extend/agent.test.ts (2)

19-21: Replace ts-expect-error with test-only type augmentation (cleaner, future-proof)

Avoid locking-in an expected error; augment Agent in test types to keep type-safety and readability.

Apply this diff in this file (remove the ts-expect-error comments):

-      // @ts-expect-error dataService no type definition
       const dataService = app.agent.dataService;
...
-      // @ts-expect-error dataServiceAsync no type definition
       const dataServiceAsync = app.agent.dataServiceAsync;

Add a test-only ambient declaration (new file) to type the properties without leaking to prod:

// packages/egg/test/types/agent-augment.d.ts
import 'egg';

declare module 'egg' {
  interface Agent {
    // Keep broad on purpose; refine later if real types are exposed
    dataService: any;
    dataServiceAsync: any;
  }
}

Also applies to: 35-37


5-5: Prefer extensionless import (drop .ts)

packages/tsconfig/tsconfig.json sets "module" and "moduleResolution" to "NodeNext"; createApp is exported at packages/egg/test/utils.ts:47 — change the import to avoid NodeNext ESM resolution pitfalls.

Apply this diff:

-import { restore, createApp, type MockApplication } from '../../utils.ts';
+import { restore, createApp, type MockApplication } from '../../utils';
plugins/onerror/CHANGELOG.md (2)

13-13: Consider wrapping bare URLs in angle brackets for better Markdown formatting.

According to Markdown best practices, bare URLs should be wrapped in angle brackets to ensure proper rendering across different parsers.

-part of https://github.com/eggjs/egg/issues/3644
+part of <https://github.com/eggjs/egg/issues/3644>

-https://github.com/eggjs/egg/issues/5257
+<https://github.com/eggjs/egg/issues/5257>

Also applies to: 15-15


42-162: Consider standardizing the changelog heading format.

The changelog uses a mix of ATX (##) and Setext (===) heading styles. For consistency, consider using ATX style throughout.

Apply this diff to standardize heading format:

-2.2.0 / 2022-12-11
-==================
+## 2.2.0 / 2022-12-11

-2.1.1 / 2022-08-18
-==================
+## 2.1.1 / 2022-08-18

# Continue this pattern for all remaining version headings...
plugins/onerror/test/fixtures/onerror-ctx-error/app/middleware/trigger.js (1)

1-7: Missing semicolon after the ctx.userId log statement.

Line 5 is missing a semicolon at the end. While JavaScript's automatic semicolon insertion will handle this, it's better to be explicit for consistency.

-    ctx.logger.info('%s', ctx.userId)
+    ctx.logger.info('%s', ctx.userId);
plugins/onerror/README.md (1)

53-53: Use more descriptive link text for better accessibility.

The link text "here" is not descriptive. Screen readers and users benefit from link text that describes the destination.

-Please open an issue [here](https://github.com/eggjs/egg/issues).
+Please open an issue on [the Egg.js GitHub repository](https://github.com/eggjs/egg/issues).
plugins/onerror/src/app.ts (3)

110-115: Guard STATUS_CODES lookup for non‑standard 5xx.

Fallback avoids undefined messages for uncommon codes.

-            errorJson = {
-              code,
-              // don't respond any error message in production env
-              message: http.STATUS_CODES[status],
-            };
+            errorJson = {
+              code,
+              // don't respond any error message in production env
+              message: http.STATUS_CODES[status] || 'Internal Server Error',
+            };

80-87: Set explicit Content‑Type for string bodies.

Be explicit to avoid relying on framework defaults.

             ctx.status = 500;
             ctx.body = `<h2>Internal Server Error, real status: ${status}</h2>`;
+            ctx.type = 'html';
             return;
           ctx.status = status;
           ctx.body = `<h2>${status} ${http.STATUS_CODES[status]}</h2>`;
+          ctx.type = 'html';
           return;
         if (app.config.env === 'unittest') {
           ctx.status = status;
           ctx.body = `${err.name}: ${err.message}\n${err.stack}`;
+          ctx.type = 'text/plain';
           return;
         }

Also applies to: 90-94


147-151: Drop unnecessary .call; pass args directly.

No this usage in json().

-        errorOptions.json!.call(ctx, err, ctx);
+        errorOptions.json!(err, ctx);
plugins/onerror/test/onerror.test.ts (3)

29-31: Fix test title grammar.

-it('should set app.config.onerror.errorPageUrl work', () => {
+it('should have app.config.onerror.errorPageUrl configured', () => {

115-120: Typo: “accpets” → “accepts”.

-it('should support custom accpets return err.stack', () => {
+it('should support custom accepts return err.stack', () => {

324-326: Remove duplicate assignment (app = app = …).

-      app = app = mm.app({
+      app = mm.app({

Also applies to: 344-346

plugins/onerror/src/lib/error_view.ts (3)

15-15: Fix regex to strip all leading slashes/backslashes (addresses CodeQL finding).

-const startingSlashRegex = /\\|\//;
+const startingSlashRegex = /^[\\/]+/;

137-141: Avoid undefined when source file is missing.

Provide a safe default for the current line.

-      line: lines[lineNumber - 1],
+      line: lines[lineNumber - 1] ?? '',

36-36: Don’t expose Authorization header on the error page.

Extend the filter list.

-  _filterHeaders = [ 'cookie', 'connection' ];
+  _filterHeaders = [ 'cookie', 'connection', 'authorization' ];
packages/mock/src/lib/mock_agent.ts (3)

3-8: Use type-only imports for Dispatcher and HttpClient to avoid runtime imports.

This prevents unnecessary values from being loaded at runtime and aligns with ESM + TS best practices.

-import {
-  MockAgent,
-  setGlobalDispatcher,
-  getGlobalDispatcher,
-  Dispatcher,
-  HttpClient,
-} from 'urllib';
+import { MockAgent, setGlobalDispatcher, getGlobalDispatcher } from 'urllib';
+import type { Dispatcher, HttpClient } from 'urllib';

12-16: Type the globals as possibly undefined to match usage.

You guard on “falsy” for __globalDispatcher and store values lazily; TS should reflect that to avoid “always truthy” checks and enable future sentinels if needed.

Suggested change:

 declare namespace globalThis {
   let __mockAgent: MockAgent | null;
-  let __globalDispatcher: Dispatcher;
-  let __httpClientDispatchers: Map<HttpClient, Dispatcher>;
+  let __globalDispatcher: Dispatcher | undefined;
+  let __httpClientDispatchers: Map<HttpClient, Dispatcher>;
 }

1-1: Rename file to hyphen-case per repo guidelines.

Suggest: mock-agent.ts

packages/mock/src/lib/parallel/app.ts (2)

23-24: Make _instance optional (or definite-assignment) to satisfy strictPropertyInitialization.

Prevents unsafe access before init and avoids relying on compiler flags.

-  _instance: EggApplication;
+  _instance?: EggApplication;

5-5: Avoid runtime import of 'egg' when only using types.

Switch to type-only import and use typeof import(...) to keep ESM tree-shakeable and eliminate an unnecessary module load.

-import { Application as EggApplication } from 'egg';
+import type { Application as EggApplication } from 'egg';
@@
-    const { Application }: { Application: typeof EggApplication } = await importModule(
+    const { Application }: { Application: typeof import('egg').Application } = await importModule(
       this.options.framework
     );

Also applies to: 44-48

packages/mock/src/app/extend/application.ts (4)

209-212: Runtime type assertion for mocked member — LGTM.

Tiny nit: consider including the containing type/class name in the error for easier debugging.


375-383: Deprecated mockUrllib with clear message — LGTM.

Consider adding a one-release warning gate in CI to catch new usages.


461-465: Preserve original logger.log call after capture — LGTM.

If custom loggers override log signature, consider guarding arity with typeof checks. Non-blocking.


468-472: Handle non-file loggers in __checkExpectLog to avoid fs.readFileSync(undefined).

Add a guard to give a clearer error when logger has no file transport and mockLog() wasn’t called.

   const filepath = logger.options.file;
-  let content;
+  let content;
   if ('_mockLogs' in logger && logger._mockLogs) {
     content = (logger._mockLogs as string[]).join('\n');
   } else {
-    content = fs.readFileSync(filepath, 'utf8');
+    assert(
+      filepath,
+      'expectLog/notExpectLog requires a file-based logger or call app.mockLog(logger) first'
+    );
+    content = fs.readFileSync(filepath, 'utf8');
   }

Also applies to: 494-497, 499-502

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbfbce8 and 01f457a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (76)
  • packages/egg/test/app/extend/agent.test.ts (2 hunks)
  • packages/egg/test/app/extend/context.test.ts (2 hunks)
  • packages/egg/test/cluster1/cluster-client.test.ts (2 hunks)
  • packages/egg/test/lib/core/httpclient.test.ts (1 hunks)
  • packages/egg/test/lib/core/loader/load_boot.test.ts (2 hunks)
  • packages/koa/tsconfig.json (1 hunks)
  • packages/mock/package.json (1 hunks)
  • packages/mock/src/app.ts (1 hunks)
  • packages/mock/src/app/extend/agent.ts (2 hunks)
  • packages/mock/src/app/extend/application.ts (13 hunks)
  • packages/mock/src/app/middleware/cluster_app_mock.ts (1 hunks)
  • packages/mock/src/lib/context.ts (0 hunks)
  • packages/mock/src/lib/mock_agent.ts (3 hunks)
  • packages/mock/src/lib/parallel/agent.ts (3 hunks)
  • packages/mock/src/lib/parallel/app.ts (3 hunks)
  • packages/mock/test/app.test.ts (1 hunks)
  • packages/supertest/tsconfig.json (1 hunks)
  • packages/utils/tsconfig.json (1 hunks)
  • plugins/onerror/CHANGELOG.md (1 hunks)
  • plugins/onerror/LICENSE (1 hunks)
  • plugins/onerror/README.md (1 hunks)
  • plugins/onerror/package.json (1 hunks)
  • plugins/onerror/src/agent.ts (1 hunks)
  • plugins/onerror/src/app.ts (1 hunks)
  • plugins/onerror/src/config/config.default.ts (1 hunks)
  • plugins/onerror/src/index.ts (1 hunks)
  • plugins/onerror/src/lib/error_view.ts (1 hunks)
  • plugins/onerror/src/lib/onerror_page.mustache.html (1 hunks)
  • plugins/onerror/src/lib/utils.ts (1 hunks)
  • plugins/onerror/src/types.ts (1 hunks)
  • plugins/onerror/test/fixtures/agent-error/agent.js (1 hunks)
  • plugins/onerror/test/fixtures/agent-error/package.json (1 hunks)
  • plugins/onerror/test/fixtures/custom-listener-onerror/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/custom-listener-onerror/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/custom-listener-onerror/package.json (1 hunks)
  • plugins/onerror/test/fixtures/mock-test-error/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-4xx/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/app/extend/context.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/app/middleware/trigger.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-ctx-error/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-500/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-500/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-500/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-custom-template/template.mustache (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-customize/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror-no-errorpage/package.json (1 hunks)
  • plugins/onerror/test/fixtures/onerror/app/controller/home.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/app/controller/user.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/app/router.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/config/config.default.js (1 hunks)
  • plugins/onerror/test/fixtures/onerror/package.json (1 hunks)
  • plugins/onerror/test/onerror.test.ts (1 hunks)
  • plugins/onerror/tsconfig.json (1 hunks)
  • plugins/onerror/tsdown.config.ts (1 hunks)
  • plugins/onerror/vitest.config.ts (1 hunks)
  • pnpm-workspace.yaml (4 hunks)
  • tools/egg-bin/tsconfig.json (1 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/mock/src/lib/context.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/mock/test/app.test.ts
  • packages/egg/test/app/extend/context.test.ts
  • packages/egg/test/lib/core/loader/load_boot.test.ts
  • packages/egg/test/lib/core/httpclient.test.ts
🚧 Files skipped from review as they are similar to previous changes (57)
  • plugins/onerror/src/index.ts
  • plugins/onerror/test/fixtures/onerror-customize/app/controller/home.js
  • plugins/onerror/test/fixtures/onerror-customize/app/controller/user.js
  • plugins/onerror/test/fixtures/onerror/package.json
  • plugins/onerror/tsconfig.json
  • plugins/onerror/test/fixtures/onerror-4xx/app/controller/home.js
  • plugins/onerror/test/fixtures/onerror-4xx/app/router.js
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/home.js
  • plugins/onerror/test/fixtures/agent-error/package.json
  • packages/koa/tsconfig.json
  • plugins/onerror/test/fixtures/custom-listener-onerror/package.json
  • plugins/onerror/test/fixtures/onerror-custom-template/app/controller/home.js
  • packages/mock/package.json
  • plugins/onerror/test/fixtures/custom-listener-onerror/config/config.default.js
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/controller/user.js
  • plugins/onerror/test/fixtures/onerror/app/controller/home.js
  • plugins/onerror/src/config/config.default.ts
  • plugins/onerror/test/fixtures/onerror-custom-500/app/router.js
  • plugins/onerror/test/fixtures/onerror/config/config.default.js
  • packages/mock/src/app/middleware/cluster_app_mock.ts
  • plugins/onerror/test/fixtures/onerror-custom-template/config/config.default.js
  • plugins/onerror/test/fixtures/onerror-custom-500/config/config.default.js
  • plugins/onerror/vitest.config.ts
  • plugins/onerror/test/fixtures/onerror-no-errorpage/package.json
  • plugins/onerror/test/fixtures/onerror-ctx-error/package.json
  • plugins/onerror/src/lib/onerror_page.mustache.html
  • plugins/onerror/test/fixtures/onerror-customize/config/config.default.js
  • plugins/onerror/test/fixtures/onerror-custom-500/package.json
  • tools/egg-bin/tsconfig.json
  • plugins/onerror/test/fixtures/onerror-customize/package.json
  • plugins/onerror/src/lib/utils.ts
  • pnpm-workspace.yaml
  • plugins/onerror/test/fixtures/onerror-4xx/config/config.default.js
  • plugins/onerror/test/fixtures/onerror/app/controller/user.js
  • plugins/onerror/test/fixtures/onerror/app/router.js
  • packages/mock/src/app.ts
  • packages/utils/tsconfig.json
  • plugins/onerror/test/fixtures/agent-error/agent.js
  • plugins/onerror/test/fixtures/onerror-no-errorpage/app/router.js
  • plugins/onerror/package.json
  • plugins/onerror/test/fixtures/onerror-no-errorpage/config/config.default.js
  • plugins/onerror/test/fixtures/onerror-4xx/package.json
  • plugins/onerror/test/fixtures/onerror-ctx-error/config/config.default.js
  • plugins/onerror/tsdown.config.ts
  • packages/mock/src/lib/parallel/agent.ts
  • plugins/onerror/test/fixtures/onerror-custom-template/package.json
  • packages/supertest/tsconfig.json
  • plugins/onerror/src/agent.ts
  • plugins/onerror/test/fixtures/onerror-custom-template/app/controller/user.js
  • plugins/onerror/test/fixtures/mock-test-error/package.json
  • plugins/onerror/src/types.ts
  • plugins/onerror/LICENSE
  • plugins/onerror/test/fixtures/onerror-customize/app/router.js
  • tsconfig.json
  • plugins/onerror/test/fixtures/onerror-custom-template/app/router.js
  • packages/mock/src/app/extend/agent.ts
  • plugins/onerror/test/fixtures/onerror-4xx/app/controller/user.js
🧰 Additional context used
📓 Path-based instructions (6)
packages/**/test/**/*.test.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/**/test/**/*.test.ts: Name test files as test/**/*.test.ts and run them with Vitest
Use import { describe, it } from 'vitest' in tests
Use Node.js built-in assert module for test assertions

Files:

  • packages/egg/test/app/extend/agent.test.ts
  • packages/egg/test/cluster1/cluster-client.test.ts
{packages,plugins}/**/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins}/**/test/**/*.test.ts: Vitest test files should follow the naming pattern test/**/*.test.ts and import from vitest
Use Node.js built-in assert for assertions in Vitest tests

Files:

  • packages/egg/test/app/extend/agent.test.ts
  • plugins/onerror/test/onerror.test.ts
  • packages/egg/test/cluster1/cluster-client.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • packages/egg/test/app/extend/agent.test.ts
  • plugins/onerror/src/lib/error_view.ts
  • packages/mock/src/lib/parallel/app.ts
  • plugins/onerror/test/onerror.test.ts
  • packages/mock/src/lib/mock_agent.ts
  • packages/egg/test/cluster1/cluster-client.test.ts
  • plugins/onerror/src/app.ts
  • packages/mock/src/app/extend/application.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Files:

  • packages/egg/test/app/extend/agent.test.ts
  • plugins/onerror/test/onerror.test.ts
  • packages/egg/test/cluster1/cluster-client.test.ts
**/test/fixtures/**

📄 CodeRabbit inference engine (AGENTS.md)

Put reusable test data under test/fixtures/

Files:

  • plugins/onerror/test/fixtures/custom-listener-onerror/app/router.js
  • plugins/onerror/test/fixtures/onerror-ctx-error/app/middleware/trigger.js
  • plugins/onerror/test/fixtures/onerror-ctx-error/app/extend/context.js
  • plugins/onerror/test/fixtures/onerror-custom-template/template.mustache
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use TypeScript for all source files in packages (no JavaScript source files)

Files:

  • packages/mock/src/lib/parallel/app.ts
  • packages/mock/src/lib/mock_agent.ts
  • packages/mock/src/app/extend/application.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must include an eggPlugin configuration field
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use Node.js built-in assert module for test assertions

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins}/**/test/**/*.test.ts : Use Node.js built-in assert for assertions in Vitest tests

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
  • plugins/onerror/test/onerror.test.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin (CLI tool) tests must use Mocha

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
  • plugins/onerror/test/onerror.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins}/**/test/**/*.test.ts : Vitest test files should follow the naming pattern test/**/*.test.ts and import from vitest

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • packages/egg/test/app/extend/agent.test.ts
🧬 Code graph analysis (6)
packages/egg/test/app/extend/agent.test.ts (1)
packages/egg/test/utils.ts (1)
  • app (40-45)
plugins/onerror/src/lib/error_view.ts (1)
plugins/onerror/src/lib/utils.ts (1)
  • detectErrorMessage (4-12)
packages/mock/src/lib/parallel/app.ts (1)
packages/utils/src/import.ts (1)
  • importModule (450-522)
packages/mock/src/lib/mock_agent.ts (1)
packages/mock/src/lib/parallel/agent.ts (2)
  • MockAgent (18-128)
  • debug (79-91)
plugins/onerror/src/app.ts (3)
plugins/onerror/src/lib/utils.ts (4)
  • detectStatus (14-22)
  • accepts (24-28)
  • isProd (30-32)
  • detectErrorMessage (4-12)
plugins/onerror/src/lib/error_view.ts (1)
  • ErrorView (27-282)
plugins/onerror/src/config/config.default.ts (1)
  • OnerrorConfig (6-26)
packages/mock/src/app/extend/application.ts (4)
packages/egg/src/index.ts (1)
  • Application (54-54)
packages/mock/src/lib/types.ts (5)
  • MockOptions (1-50)
  • MockHttpClientMethod (84-84)
  • MockResultOptions (82-82)
  • MockResultFunction (83-83)
  • MockAgent (88-88)
packages/mock/src/lib/mock_httpclient.ts (3)
  • MockHttpClientMethod (205-205)
  • MockResultOptions (7-29)
  • MockResultFunction (42-45)
packages/mock/src/lib/parallel/agent.ts (1)
  • MockAgent (18-128)
🪛 GitHub Check: CodeQL
plugins/onerror/src/lib/error_view.ts

[failure] 202-202: Incomplete string escaping or encoding
This replaces only the first occurrence of /\|//.

🪛 markdownlint-cli2 (0.18.1)
plugins/onerror/CHANGELOG.md

13-13: Bare URL used

(MD034, no-bare-urls)


15-15: Bare URL used

(MD034, no-bare-urls)


42-42: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


45-45: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


46-46: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


48-48: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


51-51: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


52-52: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


54-54: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


55-55: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


56-56: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


58-58: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


61-61: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


62-62: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


64-64: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


67-67: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


68-68: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


70-70: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


73-73: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


74-74: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


75-75: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


77-77: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


78-78: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


79-79: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


81-81: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


84-84: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


86-86: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


89-89: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


91-91: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


94-94: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


96-96: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


99-99: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


100-100: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


102-102: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


105-105: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


107-107: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


110-110: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


112-112: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


115-115: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


117-117: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


120-120: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


122-122: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


125-125: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


127-127: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


130-130: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


132-132: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


135-135: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


137-137: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


140-140: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


141-141: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


143-143: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


146-146: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


148-148: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


151-151: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


152-152: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


154-154: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


157-157: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


159-159: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


161-161: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

plugins/onerror/README.md

53-53: Link text should be descriptive

(MD059, descriptive-link-text)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Test packages (windows-latest, 24)
  • GitHub Check: Test packages (windows-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: Test egg-bin (windows-latest, 24)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 24)
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (21)
plugins/onerror/test/fixtures/custom-listener-onerror/app/router.js (1)

1-7: LGTM — minimal, focused fixture to trigger onerror with customizable name.

Fits test/fixtures conventions and should exercise the plugin as intended.

packages/egg/test/app/extend/agent.test.ts (2)

25-34: LGTM: happy path and async path assertions are clear

Good coverage of sync/async instance creation and config checks with strict assert usage.

Also applies to: 45-49


41-43: LGTM: correct use of assert.throws for the sync-only API

Regex message check is appropriate. If createInstance ever becomes async, switch this to assert.rejects.

Confirm API contract in the onerror plugin docs/spec to ensure createInstance is guaranteed to throw synchronously.

plugins/onerror/test/fixtures/onerror-ctx-error/app/extend/context.js (1)

2-4: LGTM! Clever test fixture for error handling.

The getter that throws an error is a good pattern for testing error scenarios in the onerror plugin. This ensures the error handling paths are exercised during tests.

packages/mock/src/lib/mock_agent.ts (3)

57-61: Restore logs look good.

Clear, useful context about how many clients will be restored.


61-64: Loop variable naming/readability improved.

This is clearer than generic names and makes the intent obvious.


21-21: Explicit return type is good — no void callsites found.

rg matches: packages/mock/src/app/extend/agent.ts:40, packages/mock/src/app/extend/application.ts:391, packages/mock/src/lib/mock_httpclient.ts:146–147 — all usages consume the returned MockAgent (returned or chained). No action required.

packages/mock/src/app/extend/application.ts (14)

53-55: MockContext now extends egg Context — LGTM.


85-89: Typed mockContext signature and return — LGTM.


101-104: Guard for optional _customMockContext — LGTM.


130-141: mockContextScope API typing — LGTM.


191-195: mockServiceError typing and overload behavior — LGTM.


218-221: Async vs sync origin tracking — LGTM.


228-233: Async wrapper preserves this/args — LGTM.


324-329: Header getter patch is scoped and case-insensitive — LGTM.


348-355: Alias: mockHttpclient -> mockHttpClient — LGTM.


360-371: mockHttpClient wiring to factory with cached instance — LGTM.


390-392: Typed mockAgent() return — LGTM.


9-16: Imports look good; runtime dependencies declared.
packages/mock/package.json declares "egg-logger" and "urllib" under dependencies.


301-312: createContext monkey-patch in mockCookies — teardown covered.

afterEach(mm.restore) is present in packages/mock/test/mock_cookies.test.ts and packages/mock/test/mock_headers.test.ts, so the createContext/cookies monkey-patch is restored; no change required.


57-64: Hold approval — verification found residual EggCore/EggContext/EggCoreOptions usages; verify.

rg found occurrences in multiple files (examples: packages/utils/src/plugin.ts, packages/egg/src/lib/egg.ts, packages/core/src/egg.ts and related tests/fixtures). Remove/replace these stale types or confirm they are intentionally retained and re-run the verification script.

@fengmk2 fengmk2 merged commit 130c6e1 into next Sep 20, 2025
19 of 26 checks passed
@fengmk2 fengmk2 deleted the onerror branch September 20, 2025 11:27
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

Comments