Skip to content

Commit 2155234

Browse files
committed
allow to abort client.http requests via AbortController
1 parent 3102009 commit 2155234

File tree

9 files changed

+182
-121
lines changed

9 files changed

+182
-121
lines changed

package-lock.json

Lines changed: 108 additions & 108 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "colyseus.js",
3-
"version": "0.16.17",
3+
"version": "0.16.18",
44
"description": "Colyseus Multiplayer SDK for JavaScript/TypeScript",
55
"author": "Endel Dreyer",
66
"license": "MIT",
77
"scripts": {
8-
"test": "vitest --dir test",
8+
"test": "vitest --dir test --reporter verbose",
99
"build": "rollup -c rollup.config.mjs",
1010
"build-dist-dts": "dts-bundle-generator --config dts-generator.json",
1111
"build-ci": "tsc && npm run build && npm run build-dist-dts && npm run build-zip-dist",
@@ -60,7 +60,7 @@
6060
"dependencies": {
6161
"@colyseus/msgpackr": "^1.11.2",
6262
"@colyseus/schema": "^3.0.0",
63-
"httpie": "^2.0.0-next.13",
63+
"@colyseus/httpie": "^2.0.0",
6464
"tslib": "^2.1.0",
6565
"ws": "^8.13.0"
6666
},

rollup.config.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export default [
6363
alias({
6464
entries: [
6565
// httpie: force `fetch` for web environments
66-
{ find: 'httpie', replacement: path.resolve('./node_modules/httpie/fetch/index.js') },
66+
{ find: '@colyseus/httpie', replacement: path.resolve('./node_modules/@colyseus/httpie/fetch/index.js') },
6767

6868
// ws: force browser.js version.
6969
{ find: 'ws', replacement: path.resolve('./node_modules/ws/browser.js') },
@@ -98,7 +98,7 @@ export default [
9898
alias({
9999
entries: [
100100
// httpie: force XHR implementation on browser/UMD environment
101-
{ find: 'httpie', replacement: path.resolve('./node_modules/httpie/xhr/index.js' ) },
101+
{ find: '@colyseus/httpie', replacement: path.resolve('./node_modules/@colyseus/httpie/xhr/index.js' ) },
102102

103103
// ws: force browser.js version.
104104
{ find: 'ws', replacement: path.resolve('./node_modules/ws/browser.js' ) },

src/Client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ServerError } from './errors/ServerError';
1+
import { ServerError } from './errors/Errors';
22
import { Room } from './Room';
33
import { SchemaConstructor } from './serializer/SchemaSerializer';
44
import { HTTP } from "./HTTP";

src/HTTP.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Client } from "./Client";
2-
import { ServerError } from "./errors/ServerError";
3-
import * as httpie from "httpie";
2+
import { AbortError, ServerError } from "./errors/Errors";
3+
import * as httpie from "@colyseus/httpie";
44

55
export class HTTP {
66
public authToken: string;
@@ -28,6 +28,10 @@ export class HTTP {
2828

2929
protected request(method: "get" | "post" | "put" | "del", path: string, options: Partial<httpie.Options> = {}): Promise<httpie.Response> {
3030
return httpie[method](this.client['getHttpEndpoint'](path), this.getOptions(options)).catch((e: any) => {
31+
if (e.aborted) {
32+
throw new AbortError("Request aborted");
33+
}
34+
3135
const status = e.statusCode; // || -1
3236
const message = e.data?.error || e.statusMessage || e.message; // || "offline"
3337

src/Room.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createSignal } from './core/signal';
99

1010
import { decode, encode, Iterator } from '@colyseus/schema';
1111
import { SchemaConstructor, SchemaSerializer } from './serializer/SchemaSerializer';
12-
import { CloseCode } from './errors/ServerError';
12+
import { CloseCode } from './errors/Errors';
1313

1414
import { Packr, unpack } from '@colyseus/msgpackr';
1515

src/errors/ServerError.ts renamed to src/errors/Errors.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ export class ServerError extends Error {
1313
this.code = code;
1414
}
1515
}
16+
17+
export class AbortError extends Error {
18+
constructor(message: string) {
19+
super(message);
20+
this.name = "AbortError";
21+
}
22+
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export { Client, JoinOptions, MatchMakeError, type EndpointSettings, type Client
44
export { Protocol, ErrorCode, SeatReservation } from './Protocol';
55
export { Room, RoomAvailable } from './Room';
66
export { Auth, type AuthSettings, type PopupSettings } from "./Auth";
7-
export { ServerError } from './errors/ServerError';
7+
export { ServerError } from './errors/Errors';
88

99
/*
1010
* Serializers

test/http.test.ts

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,48 @@
11
import './util';
2-
import { describe, beforeAll, test } from "vitest";
2+
import { describe, beforeAll, test, afterAll, beforeEach } from "vitest";
33
import assert from "assert";
44
import { Client } from "../src";
55

6+
import { createServer, Server } from 'http';
7+
import { AddressInfo } from 'net';
8+
import { AbortError } from '../src/errors/Errors';
9+
10+
function handler(req, res) {
11+
setTimeout(() => {
12+
res.setHeader('Content-Type', 'application/json');
13+
res.end('{invalid_json');
14+
}, 60);
15+
}
16+
17+
export async function startDummyLocalServer() {
18+
return new Promise(res => {
19+
let app = createServer(handler).listen();
20+
let close = app.close.bind(app);
21+
let { port } = app.address() as AddressInfo;
22+
return res({ port, close });
23+
});
24+
}
25+
26+
627
describe("HTTP", function() {
728
let client: Client;
29+
let localServer: any;
830

9-
beforeAll(() => {
10-
client = new Client("ws://localhost:4545");
31+
beforeAll(async () => {
32+
localServer = await startDummyLocalServer();
33+
});
34+
35+
beforeEach(() => {
36+
client = new Client(`http://localhost:${localServer.port}`);
37+
});
38+
39+
afterAll(() => {
40+
localServer.close();
1141
});
1242

1343
describe("errors", () => {
1444
test("should return 'offline' error when requesting offline service", async () => {
45+
client = new Client(`http://localhost:9090`);
1546
try {
1647
await client.http.post("/anything");
1748
} catch (e) {
@@ -20,4 +51,23 @@ describe("HTTP", function() {
2051
});
2152
});
2253

54+
describe("AbortController", () => {
55+
test("should abort request", async () => {
56+
let abortError: AbortError | undefined = undefined;
57+
58+
const controller = new AbortController();
59+
setTimeout(() => controller.abort(), 5);
60+
61+
try {
62+
await client.http.get("/anything", { signal: controller.signal });
63+
64+
} catch (e: any) {
65+
abortError = e;
66+
}
67+
68+
assert.ok(abortError);
69+
assert.strictEqual(abortError!.name, 'AbortError');
70+
});
71+
});
72+
2373
});

0 commit comments

Comments
 (0)