UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

98 lines (94 loc) 3.77 kB
import { fileURLToPath } from "node:url"; import { CustomError } from "@nomicfoundation/hardhat-utils/error"; import { shortenPath } from "@nomicfoundation/hardhat-utils/path"; import chalk from "chalk"; export class UsingHardhat2PluginError extends CustomError { callerRelativePath; constructor() { const callerPath = getCallerRelativePath(); let message; if (callerPath !== undefined) { message = `You are trying to use a Hardhat 2 plugin in a Hardhat 3 project. This file is part of a Hardhat 2 plugin calling an API that was removed in Hardhat 3: ${chalk.bold(callerPath)} Please read https://hardhat.org/migrate-from-hardhat2 to learn how to migrate your project to Hardhat 3. `; } else { message = `You are trying to use a Hardhat 2 plugin in a Hardhat 3 project. Check the stack trace below to identify which plugin is causing this. Please read https://hardhat.org/migrate-from-hardhat2 to learn how to migrate your project to Hardhat 3. `; } super(message); this.callerRelativePath = callerPath; } } /** * Returns the relative path of the file that called a deprecated Hardhat * plugin API, based on the stack trace. This helps identify which plugin * file is triggering usage of Hardhat 2 APIs in a Hardhat 3 project. * * @param {number} [depth=5] The stack trace depth to locate the caller's * source file. By default, depth 5 is used because: * 0 = message * 1 = getCallerRelativePath * 2 = UsingHardhat2PluginError constructor * 3 = throwUsingHardhat2PluginError * 4 = deprecated function * 5 = actual caller (the plugin file) * * @returns {string|undefined} The shortened relative path of the caller file, * or undefined if not found. * * @example * If the stack trace is: * // Error * // at getCallerRelativePath (src/internal/using-hardhat2-plugin-errors.ts:34:15) * // at UsingHardhat2PluginError.constructor (src/internal/using-hardhat2-plugin-errors.ts:7:3) * // at throwUsingHardhat2PluginError (src/internal/using-hardhat2-plugin-errors.ts:90:3) * // at deprecatedFunction (plugins/example-plugin/deprecated.js:50:10) * // at main (plugins/example-plugin/index.js:100:5) * Calling getCallerRelativePath() returns 'plugins/example-plugin/index.js' */ export function getCallerRelativePath(depth = 5) { try { const stack = new Error().stack; if (stack === undefined) { return undefined; } const lines = stack.split("\n"); const callerLine = lines[depth]; if (callerLine === undefined) { return undefined; } /** * Matches a single stack trace line: * * at FunctionName (path/to/file.ts:10:5) * at path/to/file.ts:10:5 * * Captures: * - group 1: file location (without line/column) */ const STACK_TRACE_LINE_REGEX = /^at (?:.+? \()?([^\(].*?)(?::\d+)?(?::\d+)?\)?$/; const match = callerLine.trim().match(STACK_TRACE_LINE_REGEX); if (match === null || match[1] === undefined) { return undefined; } let filePath = match[1]; // Handle file:// URLs from ESM stack traces if (filePath.startsWith("file://")) { filePath = fileURLToPath(filePath); } return shortenPath(filePath); } catch { return undefined; } } export function throwUsingHardhat2PluginError() { /* eslint-disable-next-line no-restricted-syntax -- Intentionally throwing a custom error here so that we always print the stack trace */ throw new UsingHardhat2PluginError(); } //# sourceMappingURL=using-hardhat2-plugin-errors.js.map