Skip to content

Commit b3d3abf

Browse files
authored
Merge pull request #103 from sparksuite/bad-status-code-error
Bad status code error
2 parents 72ed4fa + db27bdd commit b3d3abf

File tree

6 files changed

+89
-1
lines changed

6 files changed

+89
-1
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "w3c-css-validator",
3-
"version": "1.2.0",
3+
"version": "1.2.1",
44
"description": "Easily validate CSS using W3C's public CSS validator service",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class BadStatusError extends Error {
2+
statusCode: number;
3+
4+
constructor(message: string, statusCode: number) {
5+
super(message);
6+
7+
this.statusCode = statusCode;
8+
this.name = 'BadStatusError';
9+
}
10+
}
11+
12+
export default BadStatusError;

src/retrieve-validation/browser.test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//Imports
66
import retrieveFromBrowser from './browser';
77
import 'whatwg-fetch';
8+
import BadStatusError from './bad-status-error';
89

910
// Tests
1011
describe('#retrieveFromBrowser()', () => {
@@ -41,6 +42,36 @@ describe('#retrieveFromBrowser()', () => {
4142
).rejects.toThrow('The request took longer than 1ms');
4243
});
4344

45+
it('Rejects status codes other than 200-300', async () => {
46+
try {
47+
await retrieveFromBrowser(
48+
`https://jigsaw.w3.org/css-validator/validator?usermedium=all&warning=no&output=application/json&profile=css3`,
49+
3000
50+
);
51+
52+
throw new Error('This test should not proceed to this point');
53+
} catch (error: unknown) {
54+
expect(error).toBeInstanceOf(BadStatusError);
55+
56+
if (!(error instanceof BadStatusError)) {
57+
return;
58+
}
59+
60+
expect(error.statusCode).toBe(500);
61+
}
62+
});
63+
64+
it('Rejects long CSS requests with a hint', async () => {
65+
await expect(
66+
retrieveFromBrowser(
67+
`https://jigsaw.w3.org/css-validator/validator?text=${encodeURIComponent(
68+
'* { color: black }\n'.repeat(750)
69+
)}&usermedium=all&warning=no&output=application/json&profile=css3`,
70+
3000
71+
)
72+
).rejects.toThrow('This may be due to trying to validate too much CSS at once');
73+
});
74+
4475
it('Rejects unexpected errors', async () => {
4576
await expect(
4677
retrieveFromBrowser(

src/retrieve-validation/browser.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Imports
22
import { W3CCSSValidatorResponse } from '.';
3+
import BadStatusError from './bad-status-error';
34

45
// Utility function for retrieving response from W3C CSS Validator in a browser environment
56
const retrieveInBrowser = async (url: string, timeout: number): Promise<W3CCSSValidatorResponse['cssvalidation']> => {
@@ -16,11 +17,19 @@ const retrieveInBrowser = async (url: string, timeout: number): Promise<W3CCSSVa
1617

1718
try {
1819
res = await fetch(url, { signal: controller.signal });
20+
21+
if (!res.ok) {
22+
throw new BadStatusError(res.statusText, res.status);
23+
}
1924
} catch (err: unknown) {
2025
if (err instanceof Error && err.name === 'AbortError') {
2126
throw new Error(`The request took longer than ${timeout}ms`);
2227
}
2328

29+
if (err instanceof TypeError) {
30+
throw new TypeError(`${err.message} (This may be due to trying to validate too much CSS at once)`);
31+
}
32+
2433
throw err;
2534
}
2635

src/retrieve-validation/node.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//Imports
2+
import BadStatusError from './bad-status-error';
23
import retrieveFromNode from './node';
34

45
// Tests
@@ -36,6 +37,28 @@ describe('#retrieveFromNode()', () => {
3637
).rejects.toThrow('The request took longer than 1ms');
3738
});
3839

40+
it('Rejects status codes other than 200-300', async () => {
41+
try {
42+
await retrieveFromNode(
43+
`https://jigsaw.w3.org/css-validator/validator?text=${encodeURIComponent(
44+
'* { color: black }\n'.repeat(750)
45+
)}&usermedium=all&warning=no&output=application/json&profile=css3`,
46+
3000
47+
);
48+
49+
throw new Error('This test should not proceed to this point');
50+
} catch (error: unknown) {
51+
expect(error).toBeInstanceOf(BadStatusError);
52+
53+
if (!(error instanceof BadStatusError)) {
54+
return;
55+
}
56+
57+
expect(error.message).toBe('Bad request (This may be due to trying to validate too much CSS at once)');
58+
expect(error.statusCode).toBe(400);
59+
}
60+
});
61+
3962
it('Rejects unexpected errors', async () => {
4063
await expect(
4164
retrieveFromNode(

src/retrieve-validation/node.ts

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Imports
22
import * as https from 'https';
33
import { W3CCSSValidatorResponse } from '.';
4+
import BadStatusError from './bad-status-error';
45

56
// Utility function for retrieving response from W3C CSS Validator in a Node.js environment
67
const retrieveInNode = async (url: string, timeout: number): Promise<W3CCSSValidatorResponse['cssvalidation']> => {
@@ -12,6 +13,18 @@ const retrieveInNode = async (url: string, timeout: number): Promise<W3CCSSValid
1213
timeout,
1314
},
1415
(res) => {
16+
if (typeof res.statusCode === 'number' && (res.statusCode < 200 || res.statusCode >= 300)) {
17+
let message = res.statusMessage;
18+
19+
if (res.statusCode === 400) {
20+
message = message
21+
? `${message} (This may be due to trying to validate too much CSS at once)`
22+
: 'This may be due to trying to validate too much CSS at once';
23+
}
24+
25+
reject(new BadStatusError(message ?? '', res.statusCode));
26+
}
27+
1528
let data = '';
1629

1730
res.on('data', (chunk) => {

0 commit comments

Comments
 (0)