Skip to content
This repository was archived by the owner on Oct 1, 2020. It is now read-only.

Commit cb7e6c2

Browse files
fix: Suppress unhandled rejections (#59)
Suppress unhandled rejections
2 parents e2112ba + e2bab0c commit cb7e6c2

File tree

7 files changed

+96
-8
lines changed

7 files changed

+96
-8
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules/
22
.DS_Store
33
*.log*
4+
_test-output

__snapshots__/e2e_spec.js

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const debug = require('debug')('cypress:webpack')
55
const createDeferred = require('./deferred')
66
const stubbableRequire = require('./stubbable-require')
77

8-
const bundles = {}
8+
let bundles = {}
99

1010
// we don't automatically load the rules, so that the babel dependencies are
1111
// not required if a user passes in their own configuration
@@ -148,12 +148,20 @@ const preprocessor = (options = {}) => {
148148
// we overwrite the latest bundle, so that a new call to this function
149149
// returns a promise that resolves when the bundling is finished
150150
latestBundle = createDeferred()
151-
bundles[filePath] = latestBundle.promise.tap(() => {
151+
bundles[filePath] = latestBundle.promise
152+
153+
bundles[filePath].tap(() => {
152154
debug('- compile finished for', filePath)
153155
// when the bundling is finished, emit 'rerun' to let Cypress
154156
// know to rerun the spec
155157
file.emit('rerun')
156158
})
159+
// we suppress unhandled rejections so they don't bubble up to the
160+
// unhandledRejection handler and crash the process. Cypress will
161+
// eventually take care of the rejection when the file is requested.
162+
// note that this does not work if attached to latestBundle.promise
163+
// for some reason. it only works when attached after .tap ¯\_(ツ)_/¯
164+
.suppressUnhandledRejections()
157165
}
158166

159167
// when we should watch, we hook into the 'compile' hook so we know when
@@ -200,4 +208,9 @@ Object.defineProperty(preprocessor, 'defaultOptions', {
200208
},
201209
})
202210

211+
// for testing purposes
212+
preprocessor.__reset = () => {
213+
bundles = {}
214+
}
215+
203216
module.exports = preprocessor

package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828
"pretest": "npm run lint",
2929
"secure": "nsp check",
3030
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
31-
"test": "mocha",
32-
"test-watch": "chokidar '*.js' 'test/*.js' -c 'mocha'",
31+
"test": "npm run test-unit && npm run test-e2e",
32+
"test-e2e": "mocha test/e2e/*.js",
33+
"test-unit": "mocha test/unit/*.js",
34+
"test-debug": "node --inspect --debug-brk ./node_modules/.bin/_mocha",
35+
"test-watch": "chokidar '*.js' 'test/unit/*.js' -c 'npm run test-unit'",
3336
"semantic-release": "semantic-release pre && npm publish --access public && semantic-release post"
3437
},
3538
"devDependencies": {
@@ -46,6 +49,7 @@
4649
"eslint": "4.6.1",
4750
"eslint-plugin-cypress-dev": "1.1.1",
4851
"eslint-plugin-mocha": "4.11.0",
52+
"fs-extra": "8.1.0",
4953
"github-post-release": "1.13.1",
5054
"license-checker": "13.0.3",
5155
"mocha": "3.5.0",
@@ -56,6 +60,7 @@
5660
"simple-commit-message": "3.3.1",
5761
"sinon": "3.2.1",
5862
"sinon-chai": "2.13.0",
63+
"snap-shot-it": "7.9.0",
5964
"webpack": "^4.18.1"
6065
},
6166
"peerDependencies": {
@@ -67,8 +72,8 @@
6772
"babel-loader": "^8.0.2"
6873
},
6974
"dependencies": {
70-
"bluebird": "3.5.0",
71-
"debug": "3.1.0"
75+
"bluebird": "3.7.1",
76+
"debug": "4.1.1"
7277
},
7378
"release": {
7479
"verifyConditions": "condition-circle",

test/e2e/e2e_spec.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const EventEmitter = require('events').EventEmitter
2+
const expect = require('chai').expect
3+
const fs = require('fs-extra')
4+
const path = require('path')
5+
const snapshot = require('snap-shot-it')
6+
7+
const preprocessor = require('../../index')
8+
9+
describe('webpack preprocessor - e2e', () => {
10+
const outputPath = path.join(__dirname, '..', '_test-output', 'output.js')
11+
12+
let file
13+
let filePath
14+
15+
beforeEach(() => {
16+
const originalFilePath = path.join(__dirname, '..', 'fixtures', 'example_spec.js')
17+
18+
filePath = path.join(__dirname, '..', '_test-output', 'example_spec.js')
19+
20+
preprocessor.__reset()
21+
fs.removeSync(path.join(__dirname, '_test-output'))
22+
fs.outputFileSync(filePath, '')
23+
fs.copyFileSync(originalFilePath, filePath)
24+
25+
file = Object.assign(new EventEmitter(), {
26+
filePath,
27+
outputPath,
28+
})
29+
})
30+
31+
it('correctly preprocesses the file', () => {
32+
return preprocessor()(file).then(() => {
33+
snapshot(fs.readFileSync(outputPath).toString())
34+
})
35+
})
36+
37+
it('allows attaching catch later on syntax error without triggering unhandled rejection', (done) => {
38+
process.on('unhandledRejection', (err) => {
39+
// eslint-disable-next-line no-console
40+
console.error('Unhandled Rejection:', err.stack)
41+
done('Should not have trigger unhandled rejection')
42+
})
43+
44+
file.shouldWatch = true
45+
46+
preprocessor()(file).then(() => {
47+
fs.outputFileSync(filePath, '{')
48+
49+
setTimeout(() => {
50+
preprocessor()(file)
51+
.catch((err) => {
52+
expect(err.stack).to.include('Unexpected token')
53+
file.emit('close')
54+
done()
55+
})
56+
}, 1000)
57+
})
58+
})
59+
})

test/fixtures/example_spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
it('is a test', () => {
2+
const [a, b] = [1, 2]
3+
expect(a).to.equal(1)
4+
expect(b).to.equal(2)
5+
expect(Math.min(...[3, 4])).to.equal(3)
6+
})

test/index_spec.js renamed to test/unit/index_spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ mockery.enable({
1414
})
1515
mockery.registerMock('webpack', webpack)
1616

17-
const preprocessor = require('../index')
18-
const stubbableRequire = require('../stubbable-require')
17+
const preprocessor = require('../../index')
18+
const stubbableRequire = require('../../stubbable-require')
1919

2020
describe('webpack preprocessor', function () {
2121
beforeEach(function () {

0 commit comments

Comments
 (0)