hardhat 3.4.3 → 3.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.d.ts +1 -1
  3. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.d.ts.map +1 -1
  4. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js +9 -9
  5. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js.map +1 -1
  6. package/dist/src/internal/cli/telemetry/error-classification/classifier.d.ts +58 -0
  7. package/dist/src/internal/cli/telemetry/error-classification/classifier.d.ts.map +1 -0
  8. package/dist/src/internal/cli/telemetry/error-classification/classifier.js +402 -0
  9. package/dist/src/internal/cli/telemetry/error-classification/classifier.js.map +1 -0
  10. package/dist/src/internal/cli/telemetry/error-classification/codebase-dependent-helpers.d.ts +67 -0
  11. package/dist/src/internal/cli/telemetry/error-classification/codebase-dependent-helpers.d.ts.map +1 -0
  12. package/dist/src/internal/cli/telemetry/error-classification/codebase-dependent-helpers.js +140 -0
  13. package/dist/src/internal/cli/telemetry/error-classification/codebase-dependent-helpers.js.map +1 -0
  14. package/dist/src/internal/cli/telemetry/error-classification/filter.d.ts +15 -0
  15. package/dist/src/internal/cli/telemetry/error-classification/filter.d.ts.map +1 -0
  16. package/dist/src/internal/cli/telemetry/error-classification/filter.js +114 -0
  17. package/dist/src/internal/cli/telemetry/error-classification/filter.js.map +1 -0
  18. package/dist/src/internal/cli/telemetry/error-classification/helpers.d.ts +52 -0
  19. package/dist/src/internal/cli/telemetry/error-classification/helpers.d.ts.map +1 -0
  20. package/dist/src/internal/cli/telemetry/error-classification/helpers.js +163 -0
  21. package/dist/src/internal/cli/telemetry/error-classification/helpers.js.map +1 -0
  22. package/dist/src/internal/cli/telemetry/error-reporter/reporter.d.ts.map +1 -1
  23. package/dist/src/internal/cli/telemetry/error-reporter/reporter.js +14 -0
  24. package/dist/src/internal/cli/telemetry/error-reporter/reporter.js.map +1 -1
  25. package/dist/src/internal/cli/telemetry/sentry/anonymizer.d.ts +0 -2
  26. package/dist/src/internal/cli/telemetry/sentry/anonymizer.d.ts.map +1 -1
  27. package/dist/src/internal/cli/telemetry/sentry/anonymizer.js +0 -117
  28. package/dist/src/internal/cli/telemetry/sentry/anonymizer.js.map +1 -1
  29. package/dist/src/internal/cli/telemetry/sentry/init.d.ts.map +1 -1
  30. package/dist/src/internal/cli/telemetry/sentry/init.js +14 -9
  31. package/dist/src/internal/cli/telemetry/sentry/init.js.map +1 -1
  32. package/dist/src/internal/cli/telemetry/sentry/reporter.d.ts.map +1 -1
  33. package/dist/src/internal/cli/telemetry/sentry/reporter.js +1 -27
  34. package/dist/src/internal/cli/telemetry/sentry/reporter.js.map +1 -1
  35. package/dist/src/internal/cli/telemetry/sentry/subprocess.js +11 -17
  36. package/dist/src/internal/cli/telemetry/sentry/subprocess.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/internal/builtin-plugins/coverage/coverage-manager.ts +14 -10
  39. package/src/internal/cli/telemetry/error-classification/classifier.ts +636 -0
  40. package/src/internal/cli/telemetry/error-classification/codebase-dependent-helpers.ts +200 -0
  41. package/src/internal/cli/telemetry/error-classification/filter.ts +140 -0
  42. package/src/internal/cli/telemetry/error-classification/helpers.ts +235 -0
  43. package/src/internal/cli/telemetry/error-reporter/reporter.ts +21 -0
  44. package/src/internal/cli/telemetry/sentry/anonymizer.ts +0 -168
  45. package/src/internal/cli/telemetry/sentry/init.ts +42 -33
  46. package/src/internal/cli/telemetry/sentry/reporter.ts +1 -44
  47. package/src/internal/cli/telemetry/sentry/subprocess.ts +11 -19
  48. package/templates/hardhat-3/01-node-test-runner-viem/package.json +2 -2
  49. package/templates/hardhat-3/02-mocha-ethers/package.json +1 -1
  50. package/templates/hardhat-3/03-minimal/package.json +1 -1
@@ -153,174 +153,6 @@ export class Anonymizer {
153
153
  );
154
154
  }
155
155
 
156
- public filterOutEventsWithExceptionsNotRaisedByHardhat(
157
- envelope: Envelope,
158
- ): Envelope {
159
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
160
- We are just filtering events in place, not changing any type */
161
- envelope[1] = envelope[1].filter((item) => {
162
- if (item[0].type !== "event") {
163
- return true;
164
- }
165
-
166
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
167
- -- We know that the item is an event item */
168
- const eventItem = item as EventItem;
169
-
170
- return this.raisedByHardhat(eventItem[1]);
171
- }) as any;
172
-
173
- return envelope;
174
- }
175
-
176
- public raisedByHardhat(event: Event): boolean {
177
- const exceptions = event?.exception?.values;
178
-
179
- if (exceptions === undefined) {
180
- // if we can't prove that the exception doesn't come from hardhat,
181
- // we err on the side of reporting the error
182
- return true;
183
- }
184
-
185
- const originalException = exceptions[exceptions.length - 1];
186
-
187
- if (!this.#isErrorMessageAllowed(originalException)) {
188
- return false;
189
- }
190
-
191
- const frames = originalException?.stacktrace?.frames;
192
-
193
- if (frames === undefined) {
194
- return true;
195
- }
196
-
197
- for (const frame of frames.slice().reverse()) {
198
- if (frame.filename === undefined) {
199
- continue;
200
- }
201
-
202
- // We don't report errors from the Hardhat.config file
203
- if (
204
- this.#configPath !== undefined &&
205
- this.#configPath.includes(frame.filename)
206
- ) {
207
- return false;
208
- }
209
-
210
- if (this.#isPackageFile(frame.filename)) {
211
- // We don't report errors from the ignored package list e.g. `ethers`
212
- // even when buried as a subpackage of a hardhat package
213
- if (this.#errorRaisedByPackageToIgnore(frame.filename)) {
214
- return false;
215
- }
216
-
217
- // We report errors from Hardhat packages, we exclude
218
- // those from non-hardhat packages
219
- return this.#isHardhatFile(frame.filename);
220
- }
221
-
222
- // Error originating not in packages, but in the user project
223
- // should be filtered.
224
- if (this.#isUserProjectFile(frame.filename)) {
225
- return false;
226
- }
227
-
228
- // Otherwise look at the next frame up
229
- }
230
-
231
- // if we didn't find any hardhat frame, we don't report the error
232
- return false;
233
- }
234
-
235
- #isErrorMessageAllowed(originalException: Exception): boolean {
236
- const exceptionType = originalException.type;
237
- const exceptionMessage = originalException.value;
238
-
239
- // Without an exception message, we can't filter so allow it
240
- if (exceptionMessage === undefined) {
241
- return true;
242
- }
243
-
244
- // Filter out required not defined in ES Modules errors
245
- if (
246
- exceptionType === "ReferenceError" &&
247
- exceptionMessage ===
248
- "require is not defined in ES module scope, you can use import instead"
249
- ) {
250
- return false;
251
- }
252
-
253
- // Filter out cannot find package when importing errors
254
- if (
255
- exceptionType === "Error" &&
256
- /^Cannot find package '([^']+)' imported from .+$/.test(exceptionMessage)
257
- ) {
258
- return false;
259
- }
260
-
261
- // Filter out cannot find module errors
262
- if (
263
- exceptionType === "Error" &&
264
- /^Cannot find module '([^']+)'/.test(exceptionMessage)
265
- ) {
266
- return false;
267
- }
268
-
269
- // Filter out "require() cannot be sued on an ESM graph"
270
- if (
271
- exceptionType === "Error" &&
272
- exceptionMessage.startsWith(
273
- "require() cannot be used on an ESM graph with top-level await. Use import() instead.",
274
- )
275
- ) {
276
- return false;
277
- }
278
-
279
- return true;
280
- }
281
-
282
- #errorRaisedByPackageToIgnore(filename: string): boolean {
283
- // List of external packages that we don't want to report errors from
284
- const pkgsToIgnore: string[] = [
285
- path.join("node_modules", "@ethersproject"),
286
- ];
287
-
288
- // Match path separators both for Windows and Unix
289
- const pkgs = filename.match(/node_modules[\/\\][^\/\\]+/g);
290
-
291
- if (pkgs === null) {
292
- return false;
293
- }
294
-
295
- const errorSourcePkg = pkgs[pkgs.length - 1];
296
-
297
- return pkgsToIgnore.includes(errorSourcePkg);
298
- }
299
-
300
- #isHardhatFile(filename: string): boolean {
301
- const nomicFoundationPath = path.join("node_modules", "@nomicfoundation");
302
- const ignoredOrgPath = path.join("node_modules", "@ignored");
303
- const hardhatPath = path.join("node_modules", "hardhat");
304
-
305
- filename = filename.toLowerCase();
306
-
307
- return (
308
- filename.includes(nomicFoundationPath) ||
309
- filename.includes(ignoredOrgPath) ||
310
- filename.includes(hardhatPath)
311
- );
312
- }
313
-
314
- #isPackageFile(filename: string): boolean {
315
- return filename.includes("node_modules");
316
- }
317
-
318
- #isUserProjectFile(filename: string): boolean {
319
- const anonymizedUserPath = anonymizeUserPaths(filename);
320
-
321
- return anonymizedUserPath === ANONYMIZED_PATH;
322
- }
323
-
324
156
  async #anonymizeExceptions(exceptions: Exception[]): Promise<Exception[]> {
325
157
  const anonymizedExceptions = await Promise.all(
326
158
  exceptions.map((exception) => this.#anonymizeException(exception)),
@@ -3,9 +3,10 @@
3
3
  import type { ServerRuntimeClientOptions, Transport } from "@sentry/core";
4
4
 
5
5
  import os from "node:os";
6
- import path from "node:path";
7
6
 
7
+ import { getRuntimeInfo } from "@nomicfoundation/hardhat-utils/runtime";
8
8
  import {
9
+ applySdkMetadata,
9
10
  createStackParser,
10
11
  functionToStringIntegration,
11
12
  initAndBind,
@@ -61,40 +62,48 @@ interface GlobalCustomSentryReporterOptions {
61
62
  * errors integration.
62
63
  */
63
64
  export function init(options: GlobalCustomSentryReporterOptions): void {
64
- initAndBind<ServerRuntimeClient, ServerRuntimeClientOptions>(
65
- ServerRuntimeClient,
66
- {
67
- dsn: options.dsn,
68
- environment: options.environment,
69
- serverName: GENERIC_SERVER_NAME,
70
- release: options.release,
71
- initialScope: {
72
- contexts: {
73
- os: {
74
- name: os.type(),
75
- build: os.release(),
76
- version: os.version(),
77
- },
78
- device: {
79
- arch: os.arch(),
80
- },
81
- runtime: {
82
- name: path.basename(process.title),
83
- version: process.version,
84
- },
65
+ const runtimeInfo = getRuntimeInfo();
66
+ const runtime = {
67
+ name: runtimeInfo?.runtime ?? "unknown",
68
+ version: runtimeInfo?.version ?? "unknown",
69
+ };
70
+
71
+ const sentryOptions: ServerRuntimeClientOptions = {
72
+ dsn: options.dsn,
73
+ environment: options.environment,
74
+ serverName: GENERIC_SERVER_NAME,
75
+ release: options.release,
76
+ runtime,
77
+ initialScope: {
78
+ contexts: {
79
+ os: {
80
+ name: os.type(),
81
+ build: os.release(),
82
+ version: os.version(),
83
+ },
84
+ device: {
85
+ arch: os.arch(),
85
86
  },
87
+ runtime,
86
88
  },
87
- transport: () => options.transport,
88
- integrations: [
89
- functionToStringIntegration(),
90
- contextLinesIntegration(),
91
- linkedErrorsIntegration(),
92
- nodeContextIntegration(),
93
- ],
94
- platform: process.platform,
95
- stackParser: stackParserFromStackParserOptions(
96
- createStackParser(nodeStackLineParser(createGetModuleFromFilename())),
97
- ),
98
89
  },
90
+ transport: () => options.transport,
91
+ integrations: [
92
+ functionToStringIntegration(),
93
+ contextLinesIntegration(),
94
+ linkedErrorsIntegration(),
95
+ nodeContextIntegration(),
96
+ ],
97
+ platform: "javascript",
98
+ stackParser: stackParserFromStackParserOptions(
99
+ createStackParser(nodeStackLineParser(createGetModuleFromFilename())),
100
+ ),
101
+ };
102
+
103
+ applySdkMetadata(sentryOptions, "core");
104
+
105
+ initAndBind<ServerRuntimeClient, ServerRuntimeClientOptions>(
106
+ ServerRuntimeClient,
107
+ sentryOptions,
99
108
  );
100
109
  }
@@ -1,14 +1,5 @@
1
- import {
2
- HardhatError,
3
- HardhatPluginError,
4
- } from "@nomicfoundation/hardhat-errors";
5
1
  import { createDebug } from "@nomicfoundation/hardhat-utils/debug";
6
2
 
7
- import {
8
- ProviderError,
9
- UnknownError,
10
- } from "../../../builtin-plugins/network-manager/provider-errors.js";
11
- import { UsingHardhat2PluginError } from "../../../using-hardhat2-plugin-errors.js";
12
3
  import { getHardhatVersion } from "../../../utils/package.js";
13
4
  import { isTelemetryAllowed } from "../telemetry-permissions.js";
14
5
 
@@ -110,11 +101,9 @@ class Reporter {
110
101
  error: Error,
111
102
  hint?: { unhandled?: boolean; mechanismType?: string },
112
103
  ): Promise<boolean> {
113
- if (!(await this.#shouldBeReported(error))) {
114
- log("Error not send: this type of error should not be reported");
104
+ if (!this.#telemetryEnabled) {
115
105
  return false;
116
106
  }
117
-
118
107
  const { captureException, flush } = await import("@sentry/core");
119
108
 
120
109
  log("Capturing exception");
@@ -134,36 +123,4 @@ class Reporter {
134
123
 
135
124
  return true;
136
125
  }
137
-
138
- async #shouldBeReported(error: Error): Promise<boolean> {
139
- if (!this.#telemetryEnabled) {
140
- return false;
141
- }
142
-
143
- if (
144
- HardhatError.isHardhatError(error) &&
145
- !error.descriptor.shouldBeReported
146
- ) {
147
- return false;
148
- }
149
-
150
- if (error instanceof UsingHardhat2PluginError) {
151
- return false;
152
- }
153
-
154
- if (HardhatPluginError.isHardhatPluginError(error)) {
155
- // Don't log errors from third-party plugins
156
- return false;
157
- }
158
-
159
- if (
160
- ProviderError.isProviderError(error) &&
161
- error.code !== UnknownError.CODE
162
- ) {
163
- // We don't report known network related errors
164
- return false;
165
- }
166
-
167
- return true;
168
- }
169
126
  }
@@ -38,30 +38,22 @@ const envelope = JSON.parse(serializedEnvelope);
38
38
 
39
39
  const anonymizer = new Anonymizer(configPath);
40
40
 
41
- const filteredEnvelope =
42
- anonymizer.filterOutEventsWithExceptionsNotRaisedByHardhat(envelope);
41
+ const anonymizeResult = await anonymizer.anonymizeEventsFromEnvelope(envelope);
43
42
 
44
- if (filteredEnvelope[1].length === 0) {
45
- log("The events weren't raised by Hardhat, so we don't report them");
43
+ if (!anonymizeResult.success) {
44
+ log("Failed to anonymize envelope", anonymizeResult.error);
45
+ captureMessage(anonymizeResult.error);
46
46
  } else {
47
- const anonymizeResult =
48
- await anonymizer.anonymizeEventsFromEnvelope(filteredEnvelope);
47
+ try {
48
+ log("Sending received envelope to Sentry");
49
49
 
50
- if (!anonymizeResult.success) {
51
- log("Failed to anonymize envelope", anonymizeResult.error);
52
- captureMessage(anonymizeResult.error);
53
- } else {
54
- try {
55
- log("Sending received envelope to Sentry");
50
+ await sendEnvelopeToSentryBackend(dsn, anonymizeResult.envelope);
56
51
 
57
- await sendEnvelopeToSentryBackend(dsn, anonymizeResult.envelope);
52
+ log("Successfully sent received envelope to Sentry");
53
+ } catch (e) {
54
+ log("Failed to send received envelope to Sentry", e);
58
55
 
59
- log("Successfully sent received envelope to Sentry");
60
- } catch (e) {
61
- log("Failed to send received envelope to Sentry", e);
62
-
63
- captureException(e);
64
- }
56
+ captureException(e);
65
57
  }
66
58
  }
67
59
 
@@ -5,7 +5,7 @@
5
5
  "description": "A TypeScript Hardhat project using Node Test Runner and Viem",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.4.3",
8
+ "hardhat": "workspace:^3.4.4",
9
9
  "@nomicfoundation/hardhat-toolbox-viem": "workspace:^5.0.4",
10
10
  "@nomicfoundation/hardhat-ignition": "workspace:^3.1.4",
11
11
  "@types/node": "^22.8.5",
@@ -19,7 +19,7 @@
19
19
  "@nomicfoundation/hardhat-network-helpers": "workspace:^3.0.7",
20
20
  "@nomicfoundation/hardhat-node-test-runner": "workspace:^3.0.14",
21
21
  "@nomicfoundation/hardhat-viem": "workspace:^3.0.6",
22
- "@nomicfoundation/hardhat-viem-assertions": "workspace:^3.0.9",
22
+ "@nomicfoundation/hardhat-viem-assertions": "workspace:^3.0.10",
23
23
  "@nomicfoundation/hardhat-verify": "workspace:^3.0.16",
24
24
  "@nomicfoundation/ignition-core": "workspace:^3.1.4"
25
25
  }
@@ -5,7 +5,7 @@
5
5
  "description": "A TypeScript Hardhat project using Mocha and Ethers.js",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.4.3",
8
+ "hardhat": "workspace:^3.4.4",
9
9
  "@nomicfoundation/hardhat-toolbox-mocha-ethers": "workspace:^3.0.4",
10
10
  "@nomicfoundation/hardhat-ethers": "workspace:^4.0.10",
11
11
  "@nomicfoundation/hardhat-ignition": "workspace:^3.1.4",
@@ -5,7 +5,7 @@
5
5
  "description": "A minimal Hardhat project",
6
6
  "type": "module",
7
7
  "devDependencies": {
8
- "hardhat": "workspace:^3.4.3",
8
+ "hardhat": "workspace:^3.4.4",
9
9
  "@types/node": "^22.8.5",
10
10
  "typescript": "~5.8.0"
11
11
  }