Skip to content

Commit

Permalink
feat: Add details to exceptions raised in LobbyClient (#898)
Browse files Browse the repository at this point in the history
  • Loading branch information
c-w authored Jan 27, 2021
1 parent ae790e8 commit ccc9ada
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 6 deletions.
4 changes: 2 additions & 2 deletions packages/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
*/

import { Client } from '../src/client/client';
import { LobbyClient } from '../src/lobby/client';
import { LobbyClient, LobbyClientError } from '../src/lobby/client';

export { Client, LobbyClient };
export { Client, LobbyClient, LobbyClientError };
63 changes: 60 additions & 3 deletions src/lobby/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,74 @@ describe('LobbyClient', () => {

describe('status errors', () => {
beforeEach(async () => {
client = new LobbyClient();
});

test('404 throws an error', async () => {
(global as any).fetch = jest.fn(async () => ({
ok: false,
status: 404,
json: async () => {},
}));
client = new LobbyClient();
});

test('404 throws an error', async () => {
await expect(client.listGames()).rejects.toThrow('HTTP status 404');
});

test('404 throws an error with json details', async () => {
(global as any).fetch = jest.fn(async () => ({
ok: false,
status: 404,
json: async () => ({ moreInformation: 'some helpful details' }),
}));

await expect(client.listGames()).rejects.toThrow(
expect.objectContaining({
message: 'HTTP status 404',
details: {
moreInformation: 'some helpful details',
},
})
);
});

test('404 throws an error with text details', async () => {
(global as any).fetch = jest.fn(async () => ({
ok: false,
status: 404,
json: async () => {
throw new Error('impossible to parse json');
},
text: async () =>
'<moreInformation>some helpful details</moreInformation>',
}));

await expect(client.listGames()).rejects.toThrow(
expect.objectContaining({
message: 'HTTP status 404',
details: '<moreInformation>some helpful details</moreInformation>',
})
);
});

test('404 throws an error without details', async () => {
(global as any).fetch = jest.fn(async () => ({
ok: false,
status: 404,
json: async () => {
throw new Error('impossible to parse json');
},
text: async () => {
throw new Error('something went wrong in the connection');
},
}));

await expect(client.listGames()).rejects.toThrow(
expect.objectContaining({
message: 'HTTP status 404',
details: 'something went wrong in the connection',
})
);
});
});

describe('listGames', () => {
Expand Down
27 changes: 26 additions & 1 deletion src/lobby/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ const validateBody = (
}
};

export class LobbyClientError extends Error {
readonly details: any;

constructor(message: string, details: any) {
super(message);
this.details = details;
}
}

/**
* Create a boardgame.io Lobby API client.
* @param server The API’s base URL, e.g. `http://localhost:8000`.
Expand All @@ -38,7 +47,23 @@ export class LobbyClient {

private async request(route: string, init?: RequestInit) {
const response = await fetch(this.server + route, init);
if (!response.ok) throw new Error(`HTTP status ${response.status}`);

if (!response.ok) {
let details: any;

try {
details = await response.json();
} catch {
try {
details = await response.text();
} catch (error) {
details = error.message;
}
}

throw new LobbyClientError(`HTTP status ${response.status}`, details);
}

return response.json();
}

Expand Down

0 comments on commit ccc9ada

Please sign in to comment.