Skip to content

Commit

Permalink
Merge pull request #4 from MaDKaTZe/main
Browse files Browse the repository at this point in the history
Handle parse errors separately
  • Loading branch information
zupper committed Apr 20, 2021
2 parents 4195e77 + 278515f commit 47d39ff
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 13 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@luckbox/http-adapter-factory",
"version": "1.0.2",
"version": "1.1.0",
"description": "Easy to use http adapter factory with support for GET/POST.",
"author": "Luckbox",
"main": "dist/index.js",
Expand Down
9 changes: 9 additions & 0 deletions src/GotHttpAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import got, {
RequestError,
OptionsOfUnknownResponseBody,
Response as GotResponse,
ParseError as GotParseError,
} from 'got';
import * as qs from 'qs';

Expand All @@ -23,6 +24,7 @@ import HttpAdapter, {
DEFAULTS,
} from './HttpAdapter';
import { IncomingHttpHeaders } from 'http';
import ParseError from './errors/ParseError';

class GotHttpAdapter implements HttpAdapter {
private readonly timeout: number;
Expand Down Expand Up @@ -126,6 +128,13 @@ class GotHttpAdapter implements HttpAdapter {
});
}

if (err instanceof GotParseError) {
throw new ParseError({
message: err.message.split(/\sin\s+"?https?:\/{2}/i, 1)[0],
responseBody: err.response.rawBody.toString(),
});
}

if (err instanceof RequestError && err.name === 'RequestError') {
throw new HttpRequestError({
message: err.message,
Expand Down
17 changes: 17 additions & 0 deletions src/errors/ParseError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
type ConstructorParams = {
message: string;
responseBody: string;
}

class ParseError extends Error {
public readonly responseBody: string;

constructor(params: ConstructorParams) {
super(params.message);

this.name = 'ParseError';
this.responseBody = params.responseBody;
}
}

export default ParseError;
69 changes: 58 additions & 11 deletions src/tests/GotHttpAdapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import got, { HTTPError, ParseError, RequestError } from 'got';
import got, { HTTPError, ParseError as GotParseError, RequestError } from 'got';
import ParseError from '../errors/ParseError';
import HttpGenericError from '../errors/HttpGenericError';
import HttpRequestError from '../errors/HttpRequestError';
import HttpStatusCodeError from '../errors/HttpStatusCodeError';
Expand Down Expand Up @@ -176,10 +177,10 @@ describe('GotHttpAdapter', () => {
});

it('should throw HttpGenericError when got throws subclass of RequestError', async () => {
const parseError = produceFoolInstance(ParseError);
parseError.message = 'Unexpected token < at position...';
parseError.name = 'ParseError';
mockGot.get.mockRejectedValueOnce(parseError);
const timeoutError = produceFoolInstance(RequestError);
timeoutError.message = 'Connection has timed out';
timeoutError.name = 'TimeoutError';
mockGot.get.mockRejectedValueOnce(timeoutError);

let caughtErr;
const url = 'http://example.com';
Expand All @@ -190,7 +191,30 @@ describe('GotHttpAdapter', () => {
}

expect(caughtErr).toBeInstanceOf(HttpGenericError);
expect(caughtErr.originalError).toEqual(parseError);
expect(caughtErr.originalError).toEqual(timeoutError);
});

it('should throw ParseError when got throws ParseError', async () => {
const parseError = produceFoolInstance(GotParseError, {
message: 'Unexpected token < at position 10 in "http://example.com"',
name: 'ParseError',
response: {
rawBody: Buffer.from('Invalid JSON'),
},
});

mockGot.post.mockRejectedValueOnce(parseError);

let caughtErr;

try {
await httpAdapter.post('http://example.com');
} catch (err) {
caughtErr = err;
}

expect(caughtErr).toBeInstanceOf(ParseError);
expect(caughtErr.message).toEqual('Unexpected token < at position 10');
});
});

Expand Down Expand Up @@ -336,11 +360,11 @@ describe('GotHttpAdapter', () => {
});

it('should throw HttpGenericError when got throws subclass of RequestError', async () => {
const parseError = produceFoolInstance(ParseError, {
message: 'Unexpected token < at position...',
name: 'ParseError',
const unexpectedCloseError = produceFoolInstance(RequestError, {
message: 'Connection has been closed unexpectedly',
name: 'UnexpectedCloseError',
});
mockGot.post.mockRejectedValueOnce(parseError);
mockGot.post.mockRejectedValueOnce(unexpectedCloseError);

let caughtErr;
const url = 'http://example.com';
Expand All @@ -351,7 +375,30 @@ describe('GotHttpAdapter', () => {
}

expect(caughtErr).toBeInstanceOf(HttpGenericError);
expect(caughtErr.originalError).toEqual(parseError);
expect(caughtErr.originalError).toEqual(unexpectedCloseError);
});

it('should throw ParseError when got throws ParseError', async () => {
const parseError = produceFoolInstance(GotParseError, {
message: 'Unexpected token < at position 10 in "http://example.com"',
name: 'ParseError',
response: {
rawBody: Buffer.from('Invalid JSON'),
},
});

mockGot.post.mockRejectedValueOnce(parseError);

let caughtErr;

try {
await httpAdapter.post('http://example.com');
} catch (err) {
caughtErr = err;
}

expect(caughtErr).toBeInstanceOf(ParseError);
expect(caughtErr.message).toEqual('Unexpected token < at position 10');
});
});
});
Expand Down

0 comments on commit 47d39ff

Please sign in to comment.