Skip to content

Commit 0b58fe7

Browse files
authored
Merge pull request #96 from takker99/change-error-data
💥 Make UnexpectedResponseError have Request and Response
2 parents 5d09e71 + 0d8f263 commit 0b58fe7

File tree

12 files changed

+158
-297
lines changed

12 files changed

+158
-297
lines changed

rest/error.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1+
import type { ErrorLike } from "../deps/scrapbox-rest.ts";
2+
import { tryToErrorLike } from "../is.ts";
3+
4+
/** 想定されない応答が帰ってきたときに投げる例外 */
15
export class UnexpectedResponseError extends Error {
26
name = "UnexpectedResponseError";
3-
status: number;
4-
statusText: string;
5-
body: string;
6-
path: URL;
7+
request: Request;
8+
response: Response;
79

810
constructor(
9-
init: { status: number; statusText: string; body: string; path: URL },
11+
init: { request: Request; response: Response },
1012
) {
1113
super(
12-
`${init.status} ${init.statusText} when fetching ${init.path.toString()}`,
14+
`${init.response.status} ${init.response.statusText} when fetching ${init.request.url}`,
1315
);
1416

15-
this.status = init.status;
16-
this.statusText = init.statusText;
17-
this.body = init.body;
18-
this.path = init.path;
17+
this.request = init.request.clone();
18+
this.response = init.response.clone();
1919

2020
// @ts-ignore only available on V8
2121
if (Error.captureStackTrace) {
@@ -24,3 +24,20 @@ export class UnexpectedResponseError extends Error {
2424
}
2525
}
2626
}
27+
28+
/** 失敗した要求からエラー情報を取り出す */
29+
export const makeError = async <T extends ErrorLike>(
30+
req: Request,
31+
res: Response,
32+
): Promise<{ ok: false; value: T }> => {
33+
const response = res.clone();
34+
const text = await response.text();
35+
const value = tryToErrorLike(text);
36+
if (!value) {
37+
throw new UnexpectedResponseError({ request: req, response });
38+
}
39+
return {
40+
ok: false,
41+
value: value as T,
42+
};
43+
};

rest/getGyazoToken.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { NotLoggedInError } from "../deps/scrapbox-rest.ts";
22
import { cookie } from "./auth.ts";
3-
import { UnexpectedResponseError } from "./error.ts";
4-
import { tryToErrorLike } from "../is.ts";
3+
import { makeError } from "./error.ts";
54
import { BaseOptions, Result, setDefaults } from "./util.ts";
65

76
export interface GetGyazoTokenOptions extends BaseOptions {
@@ -26,26 +25,19 @@ export const getGyazoToken = async (
2625
>
2726
> => {
2827
const { sid, hostName, gyazoTeamsName } = setDefaults(init ?? {});
29-
const path = `https://${hostName}/api/login/gyazo/oauth-upload/token${
30-
gyazoTeamsName ? `?gyazoTeamsName=${gyazoTeamsName}` : ""
31-
}`;
32-
33-
const res = await fetch(
34-
path,
28+
const req = new Request(
29+
`https://${hostName}/api/login/gyazo/oauth-upload/token${
30+
gyazoTeamsName ? `?gyazoTeamsName=${gyazoTeamsName}` : ""
31+
}`,
3532
sid ? { headers: { Cookie: cookie(sid) } } : undefined,
3633
);
3734

35+
const res = await fetch(req);
3836
if (!res.ok) {
39-
const text = await res.text();
40-
const value = tryToErrorLike(text);
41-
if (!value) {
42-
throw new UnexpectedResponseError({
43-
path: new URL(path),
44-
...res,
45-
body: await res.text(),
46-
});
47-
}
48-
return { ok: false, value: value as NotLoggedInError };
37+
return makeError<NotLoggedInError>(
38+
req,
39+
res,
40+
);
4941
}
5042

5143
const { token } = (await res.json()) as { token?: string };

rest/getSnapshots.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import type {
66
PageSnapshot,
77
Snapshot,
88
} from "../deps/scrapbox-rest.ts";
9-
import { tryToErrorLike } from "../is.ts";
109
import { cookie } from "./auth.ts";
1110
import { BaseOptions, Result, setDefaults } from "./util.ts";
12-
import { UnexpectedResponseError } from "./error.ts";
11+
import { makeError } from "./error.ts";
1312

1413
/** 不正なfollowingIdを渡されたときに発生するエラー */
1514
export interface InvalidPageSnapshotIdError extends ErrorLike {
@@ -39,15 +38,16 @@ export const getSnapshots = async (
3938
>
4039
> => {
4140
const { sid, hostName, fetch, followingId } = setDefaults(options ?? {});
42-
const path = `https://${hostName}/api/page-snapshots/${project}/${pageId}/${
43-
followingId ? `?followingId=${followingId}` : ""
44-
}`;
4541

46-
const res = await fetch(
47-
path,
42+
const req = new Request(
43+
`https://${hostName}/api/page-snapshots/${project}/${pageId}/${
44+
followingId ? `?followingId=${followingId}` : ""
45+
}`,
4846
sid ? { headers: { Cookie: cookie(sid) } } : undefined,
4947
);
5048

49+
const res = await fetch(req);
50+
5151
if (!res.ok) {
5252
if (res.status === 422) {
5353
return {
@@ -58,19 +58,10 @@ export const getSnapshots = async (
5858
},
5959
};
6060
}
61-
const text = await res.text();
62-
const value = tryToErrorLike(text);
63-
if (!value) {
64-
throw new UnexpectedResponseError({
65-
path: new URL(path),
66-
...res,
67-
body: text,
68-
});
69-
}
70-
return {
71-
ok: false,
72-
value: value as (NotFoundError | NotLoggedInError | NotMemberError),
73-
};
61+
return makeError<NotFoundError | NotLoggedInError | NotMemberError>(
62+
req,
63+
res,
64+
);
7465
}
7566

7667
const data = (await res.json()) as PageSnapshot;

rest/getTweetInfo.ts

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import type {
55
TweetInfo,
66
} from "../deps/scrapbox-rest.ts";
77
import { cookie, getCSRFToken } from "./auth.ts";
8-
import { UnexpectedResponseError } from "./error.ts";
9-
import { tryToErrorLike } from "../is.ts";
8+
import { makeError } from "./error.ts";
109
import { ExtendedOptions, Result, setDefaults } from "./util.ts";
1110

1211
/** 指定したTweetの情報を取得する
@@ -27,12 +26,10 @@ export const getTweetInfo = async (
2726
>
2827
> => {
2928
const { sid, hostName, fetch, csrf } = setDefaults(init ?? {});
30-
const path = `https://${hostName}/api/embed-text/twitter?url=${
31-
encodeURIComponent(url.toString())
32-
}`;
33-
34-
const res = await fetch(
35-
path,
29+
const req = new Request(
30+
`https://${hostName}/api/embed-text/twitter?url=${
31+
encodeURIComponent(url.toString())
32+
}`,
3633
{
3734
method: "POST",
3835
headers: {
@@ -44,6 +41,8 @@ export const getTweetInfo = async (
4441
},
4542
);
4643

44+
const res = await fetch(req);
45+
4746
if (!res.ok) {
4847
if (res.status === 422) {
4948
return {
@@ -54,21 +53,7 @@ export const getTweetInfo = async (
5453
},
5554
};
5655
}
57-
const text = await res.text();
58-
const value = tryToErrorLike(text);
59-
if (!value) {
60-
throw new UnexpectedResponseError({
61-
path: new URL(path),
62-
...res,
63-
body: text,
64-
});
65-
}
66-
return {
67-
ok: false,
68-
value: value as
69-
| SessionError
70-
| BadRequestError,
71-
};
56+
return makeError<SessionError | BadRequestError>(req, res);
7257
}
7358

7459
const tweet = (await res.json()) as TweetInfo;

rest/getWebPageTitle.ts

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import type {
44
SessionError,
55
} from "../deps/scrapbox-rest.ts";
66
import { cookie, getCSRFToken } from "./auth.ts";
7-
import { UnexpectedResponseError } from "./error.ts";
8-
import { tryToErrorLike } from "../is.ts";
7+
import { makeError } from "./error.ts";
98
import { ExtendedOptions, Result, setDefaults } from "./util.ts";
109

1110
/** 指定したURLのweb pageのtitleをscrapboxのserver経由で取得する
@@ -26,12 +25,11 @@ export const getWebPageTitle = async (
2625
>
2726
> => {
2827
const { sid, hostName, fetch, csrf } = setDefaults(init ?? {});
29-
const path = `https://${hostName}/api/embed-text/url?url=${
30-
encodeURIComponent(url.toString())
31-
}`;
3228

33-
const res = await fetch(
34-
path,
29+
const req = new Request(
30+
`https://${hostName}/api/embed-text/url?url=${
31+
encodeURIComponent(url.toString())
32+
}`,
3533
{
3634
method: "POST",
3735
headers: {
@@ -43,6 +41,8 @@ export const getWebPageTitle = async (
4341
},
4442
);
4543

44+
const res = await fetch(req);
45+
4646
if (!res.ok) {
4747
if (res.status === 422) {
4848
return {
@@ -53,21 +53,7 @@ export const getWebPageTitle = async (
5353
},
5454
};
5555
}
56-
const text = await res.text();
57-
const value = tryToErrorLike(text);
58-
if (!value) {
59-
throw new UnexpectedResponseError({
60-
path: new URL(path),
61-
...res,
62-
body: text,
63-
});
64-
}
65-
return {
66-
ok: false,
67-
value: value as
68-
| SessionError
69-
| BadRequestError,
70-
};
56+
return makeError<SessionError | BadRequestError>(req, res);
7157
}
7258

7359
const { title } = (await res.json()) as { title: string };

rest/link.ts

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import type {
55
SearchedTitle,
66
} from "../deps/scrapbox-rest.ts";
77
import { cookie } from "./auth.ts";
8-
import { UnexpectedResponseError } from "./error.ts";
9-
import { tryToErrorLike } from "../is.ts";
8+
import { makeError } from "./error.ts";
109
import { BaseOptions, Result, setDefaults } from "./util.ts";
1110

1211
/** 不正なfollowingIdを渡されたときに発生するエラー */
@@ -33,15 +32,16 @@ export const getLinks = async (
3332
}, NotFoundError | NotLoggedInError | InvalidFollowingIdError>
3433
> => {
3534
const { sid, hostName, fetch, followingId } = setDefaults(options ?? {});
36-
const path = `https://${hostName}/api/pages/${project}/search/titles${
37-
followingId ? `?followingId=${followingId}` : ""
38-
}`;
3935

40-
const res = await fetch(
41-
path,
36+
const req = new Request(
37+
`https://${hostName}/api/pages/${project}/search/titles${
38+
followingId ? `?followingId=${followingId}` : ""
39+
}`,
4240
sid ? { headers: { Cookie: cookie(sid) } } : undefined,
4341
);
4442

43+
const res = await fetch(req);
44+
4545
if (!res.ok) {
4646
if (res.status === 422) {
4747
return {
@@ -52,17 +52,10 @@ export const getLinks = async (
5252
},
5353
};
5454
}
55-
const text = await res.text();
56-
const value = tryToErrorLike(text);
57-
if (!value) {
58-
throw new UnexpectedResponseError({
59-
path: new URL(path),
60-
...res,
61-
body: text,
62-
});
63-
}
64-
return { ok: false, value: value as NotFoundError | NotLoggedInError };
55+
56+
return makeError<NotFoundError | NotLoggedInError>(req, res);
6557
}
58+
6659
const pages = (await res.json()) as SearchedTitle[];
6760
return {
6861
ok: true,

0 commit comments

Comments
 (0)