Skip to content

Commit

Permalink
Simplify errorFromResponse (#111)
Browse files Browse the repository at this point in the history
Should be a no-op other than no longer having `error.name`.

(There's an argument to be made that there's nothing GraphQL-specific
left in RESTDataSource other than this error and we shouldn't use
GraphQLError at all, but eh.)
  • Loading branch information
glasser authored Dec 7, 2022
1 parent a3db089 commit c384821
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 39 deletions.
46 changes: 13 additions & 33 deletions src/RESTDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,29 +242,23 @@ export abstract class RESTDataSource {
}

protected async errorFromResponse(response: FetcherResponse) {
const message = `${response.status}: ${response.statusText}`;

let error: GraphQLError;
if (response.status === 401) {
error = new AuthenticationError(message);
} else if (response.status === 403) {
error = new ForbiddenError(message);
} else {
error = new GraphQLError(message);
}

const body = await this.parseBody(response);

Object.assign(error.extensions, {
response: {
url: response.url,
status: response.status,
statusText: response.statusText,
body,
return new GraphQLError(`${response.status}: ${response.statusText}`, {
extensions: {
...(response.status === 401
? { code: 'UNAUTHENTICATED' }
: response.status === 403
? { code: 'FORBIDDEN' }
: {}),
response: {
url: response.url,
status: response.status,
statusText: response.statusText,
body,
},
},
});

return error;
}

protected async get<TResult = any>(
Expand Down Expand Up @@ -438,17 +432,3 @@ export abstract class RESTDataSource {
}
}
}

export class AuthenticationError extends GraphQLError {
constructor(message: string) {
super(message, { extensions: { code: 'UNAUTHENTICATED' } });
this.name = 'AuthenticationError';
}
}

export class ForbiddenError extends GraphQLError {
constructor(message: string) {
super(message, { extensions: { code: 'FORBIDDEN' } });
this.name = 'ForbiddenError';
}
}
10 changes: 4 additions & 6 deletions src/__tests__/RESTDataSource.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import {
AugmentedRequest,
AuthenticationError,
CacheOptions,
DataSourceConfig,
ForbiddenError,
RequestDeduplicationPolicy,
RequestOptions,
RESTDataSource,
Expand Down Expand Up @@ -803,7 +801,7 @@ describe('RESTDataSource', () => {
});

describe('error handling', () => {
it('throws an AuthenticationError when the response status is 401', async () => {
it('throws an UNAUTHENTICATED error when the response status is 401', async () => {
const dataSource = new (class extends RESTDataSource {
override baseURL = 'https://api.example.com';

Expand All @@ -815,7 +813,7 @@ describe('RESTDataSource', () => {
nock(apiUrl).get('/foo').reply(401, 'Invalid token');

const result = dataSource.getFoo();
await expect(result).rejects.toThrow(AuthenticationError);
await expect(result).rejects.toThrow(GraphQLError);
await expect(result).rejects.toMatchObject({
extensions: {
code: 'UNAUTHENTICATED',
Expand All @@ -827,7 +825,7 @@ describe('RESTDataSource', () => {
});
});

it('throws a ForbiddenError when the response status is 403', async () => {
it('throws a FORBIDDEN error when the response status is 403', async () => {
const dataSource = new (class extends RESTDataSource {
override baseURL = 'https://api.example.com';

Expand All @@ -839,7 +837,7 @@ describe('RESTDataSource', () => {
nock(apiUrl).get('/foo').reply(403, 'No access');

const result = dataSource.getFoo();
await expect(result).rejects.toThrow(ForbiddenError);
await expect(result).rejects.toThrow(GraphQLError);
await expect(result).rejects.toMatchObject({
extensions: {
code: 'FORBIDDEN',
Expand Down

0 comments on commit c384821

Please sign in to comment.