Skip to content

Commit 3825d5b

Browse files
authored
Merge pull request #94 from sparksuite/catch-callback-error
Fix errors thrown in node environments not being caught
2 parents 6d580bb + dc6315f commit 3825d5b

File tree

7 files changed

+159
-3
lines changed

7 files changed

+159
-3
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"rugged": "^1.0.0",
4848
"ts-jest": "^26.5.2",
4949
"ts-node": "^9.1.1",
50-
"typescript": "^4.1.3"
50+
"typescript": "^4.1.3",
51+
"whatwg-fetch": "^3.6.2"
5152
}
5253
}
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
5+
//Imports
6+
import retrieveFromBrowser from './browser';
7+
import 'whatwg-fetch';
8+
9+
// Tests
10+
describe('#retrieveFromBrowser()', () => {
11+
afterEach(
12+
() => new Promise<void>((resolve) => setTimeout(resolve, 1000))
13+
);
14+
15+
it('Retrieves the results from the W3C Validator API', async () => {
16+
expect(
17+
await retrieveFromBrowser(
18+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/json&profile=css3',
19+
3000
20+
)
21+
).toStrictEqual({
22+
validity: true,
23+
checkedby: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
24+
csslevel: 'css3',
25+
date: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
26+
result: {
27+
errorcount: 0,
28+
warningcount: 0,
29+
},
30+
timestamp: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
31+
uri: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
32+
});
33+
});
34+
35+
it('Rejects when the request takes longer than the timeout', async () => {
36+
await expect(
37+
retrieveFromBrowser(
38+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/json&profile=css3',
39+
1
40+
)
41+
).rejects.toThrow('The request took longer than 1ms');
42+
});
43+
44+
it('Rejects unexpected errors', async () => {
45+
await expect(
46+
retrieveFromBrowser(
47+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/xml&profile=css3',
48+
3000
49+
)
50+
).rejects.toThrow();
51+
});
52+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
5+
// Imports
6+
import retrieveValidation from '.';
7+
import retrieveInBrowser from './browser';
8+
import 'whatwg-fetch';
9+
10+
// Mocks
11+
jest.mock('./browser');
12+
13+
// Tests
14+
describe('#retrieveValidation()', () => {
15+
it('Uses retrieveInBrowser() when the Fetch API is available', async () => {
16+
require('whatwg-fetch');
17+
18+
await retrieveValidation(
19+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/json&profile=css3',
20+
3000
21+
);
22+
23+
expect(retrieveInBrowser as jest.Mock).toBeCalled();
24+
});
25+
});
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Imports
2+
import retrieveValidation from '.';
3+
import retrieveInNode from './node';
4+
5+
// Mocks
6+
jest.mock('./node');
7+
8+
// Tests
9+
describe('#retrieveValidation()', () => {
10+
it('Uses retrieveInNode() when the Fetch API is not available', async () => {
11+
await retrieveValidation(
12+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/json&profile=css3',
13+
3000
14+
);
15+
16+
expect(retrieveInNode as jest.Mock).toBeCalled();
17+
});
18+
});

src/retrieve-validation/node.test.ts

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//Imports
2+
import retrieveFromNode from './node';
3+
4+
// Tests
5+
describe('#retrieveFromNode()', () => {
6+
afterEach(
7+
() => new Promise<void>((resolve) => setTimeout(resolve, 1000))
8+
);
9+
10+
it('Retrieves the results from the W3C Validator API', async () => {
11+
expect(
12+
await retrieveFromNode(
13+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/json&profile=css3',
14+
3000
15+
)
16+
).toStrictEqual({
17+
validity: true,
18+
checkedby: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
19+
csslevel: 'css3',
20+
date: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
21+
result: {
22+
errorcount: 0,
23+
warningcount: 0,
24+
},
25+
timestamp: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
26+
uri: expect.any(String), // eslint-disable-line @typescript-eslint/no-unsafe-assignment
27+
});
28+
});
29+
30+
it('Rejects when the request takes longer than the timeout', async () => {
31+
await expect(
32+
retrieveFromNode(
33+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/json&profile=css3',
34+
1
35+
)
36+
).rejects.toThrow('The request took longer than 1ms');
37+
});
38+
39+
it('Rejects unexpected errors', async () => {
40+
await expect(
41+
retrieveFromNode(
42+
'https://jigsaw.w3.org/css-validator/validator?text=.foo%20%7B%20text-align%3A%20center%3B%20%7D&usermedium=all&warning=no&output=application/xml&profile=css3',
43+
3000
44+
)
45+
).rejects.toThrow();
46+
});
47+
});

src/retrieve-validation/node.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ const retrieveInNode = async (url: string, timeout: number): Promise<W3CCSSValid
1515
let data = '';
1616

1717
res.on('data', (chunk) => {
18-
data += chunk;
18+
try {
19+
data += chunk;
20+
} catch (error) {
21+
reject(error);
22+
}
1923
});
2024

2125
res.on('end', () => {
22-
resolve((JSON.parse(data) as W3CCSSValidatorResponse).cssvalidation);
26+
try {
27+
resolve((JSON.parse(data) as W3CCSSValidatorResponse).cssvalidation);
28+
} catch (error) {
29+
reject(error);
30+
}
2331
});
2432
}
2533
);

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -4751,6 +4751,11 @@ whatwg-encoding@^1.0.5:
47514751
dependencies:
47524752
iconv-lite "0.4.24"
47534753

4754+
whatwg-fetch@^3.6.2:
4755+
version "3.6.2"
4756+
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c"
4757+
integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==
4758+
47544759
whatwg-mimetype@^2.3.0:
47554760
version "2.3.0"
47564761
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"

0 commit comments

Comments
 (0)