Skip to content

Commit

Permalink
Include a less cryptic error message when trying to require an ES mod…
Browse files Browse the repository at this point in the history
…ule (#2264)
  • Loading branch information
michael-lloyd-morris committed Mar 28, 2023
1 parent aae711c commit d599dfe
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Please see [CONTRIBUTING.md](./CONTRIBUTING.md) on how to contribute to Cucumber.

## [Unreleased]

### Added
- Formatters create sub-directory automatically instead of failing ([#2266](https://github.com/cucumber/cucumber-js/pull/2266))
- Include a less cryptic error message when trying to `require` an ES module ([#2264](https://github.com/cucumber/cucumber-js/pull/2264))

### Changed
- Change hashes type from `any` to `Record<string, string>` in `DataTable` ([#2270](https://github.com/cucumber/cucumber-js/pull/2270))
Expand Down
20 changes: 20 additions & 0 deletions features/esm.feature
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,23 @@ Feature: ES modules support
When I run cucumber-js
Then it runs 2 scenarios
And it passes

Scenario: ES module invoked with --require
Given a file named "features/a.feature" with:
"""
Feature:
Scenario: one
Given a step passes
"""
And a file named "features/step_definitions/cucumber_steps.js" with:
"""
import {Given} from '@cucumber/cucumber'
Given(/^a step passes$/, function() {});
"""
When I run cucumber-js with `--require features/**/*.js`
Then it fails
And the error output contains the text:
"""
Error: Cucumber expected a CommonJS module
"""
8 changes: 6 additions & 2 deletions src/api/support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IdGenerator } from '@cucumber/messages'
import { ISupportCodeLibrary } from '../support_code_library_builder/types'
import supportCodeLibraryBuilder from '../support_code_library_builder'
import { pathToFileURL } from 'url'
import tryRequire from '../try_require'

// eslint-disable-next-line @typescript-eslint/no-var-requires
const { importer } = require('../importer')
Expand All @@ -24,10 +25,13 @@ export async function getSupportCodeLibrary({
requirePaths,
importPaths,
})
requireModules.map((module) => require(module))
requirePaths.map((path) => require(path))

requireModules.map((module) => tryRequire(module))
requirePaths.map((path) => tryRequire(path))

for (const path of importPaths) {
await importer(pathToFileURL(path))
}

return supportCodeLibraryBuilder.finalize()
}
5 changes: 3 additions & 2 deletions src/runtime/parallel/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
IWorkerCommandInitialize,
IWorkerCommandRun,
} from './command_types'
import tryRequire from '../../try_require'

// eslint-disable-next-line @typescript-eslint/no-var-requires
const { importer } = require('../../importer')
Expand Down Expand Up @@ -74,8 +75,8 @@ export default class Worker {
requirePaths,
importPaths,
})
requireModules.map((module) => require(module))
requirePaths.map((module) => require(module))
requireModules.map((module) => tryRequire(module))
requirePaths.map((module) => tryRequire(module))
for (const path of importPaths) {
await importer(pathToFileURL(path))
}
Expand Down
22 changes: 22 additions & 0 deletions src/try_require.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* Provides a try guarded require call that will throw a more detailed error when
* the ERR_REQUIRE_ESM error code is encountered.
*
* @param {string} path File path to require from.
*/
export default function tryRequire(path: string) {
try {
return require(path)
} catch (error) {
if (error.code === 'ERR_REQUIRE_ESM') {
throw Error(
`Cucumber expected a CommonJS module at '${path}' but found an ES module.
Either change the file to CommonJS syntax or use the --import directive instead of --require.
Original error message: ${error.message}`
)
} else {
throw error
}
}
}

0 comments on commit d599dfe

Please sign in to comment.