Skip to content

Commit f3539cf

Browse files
fix: update pages.ts to use createTargetedResponse for consistent error handling
1 parent 3a15985 commit f3539cf

File tree

13 files changed

+500
-177
lines changed

13 files changed

+500
-177
lines changed

browser/websocket/pull.ts

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
1-
import {
2-
createErr,
3-
createOk,
4-
isErr,
5-
mapForResult,
6-
type Result,
7-
unwrapOk,
8-
} from "option-t/plain_result";
91
import type {
2+
GuestUser,
3+
MemberUser,
104
NotFoundError,
115
NotLoggedInError,
126
NotMemberError,
137
Page,
148
} from "@cosense/types/rest";
9+
import {
10+
createErrorResponse,
11+
createSuccessResponse,
12+
} from "../../rest/utils.ts";
1513
import {
1614
getPage,
1715
type GetPageOption,
1816
type TooLongURIError,
1917
} from "../../rest/pages.ts";
2018
import { getProfile } from "../../rest/profile.ts";
2119
import { getProject } from "../../rest/project.ts";
22-
import type { HTTPError } from "../../rest/responseIntoResult.ts";
20+
import type { HTTPError } from "../../rest/errors.ts";
2321
import type { AbortError, NetworkError } from "../../rest/robustFetch.ts";
2422
import type { BaseOptions } from "../../rest/options.ts";
23+
import type { TargetedResponse } from "../../rest/targeted_response.ts";
2524

2625
export interface PushMetadata extends Page {
2726
projectId: string;
@@ -42,42 +41,70 @@ export const pull = async (
4241
project: string,
4342
title: string,
4443
options?: GetPageOption,
45-
): Promise<Result<PushMetadata, PullError>> => {
44+
): Promise<
45+
TargetedResponse<200 | 400 | 404 | 408 | 500, PushMetadata | PullError>
46+
> => {
4647
const [pageRes, userRes, projectRes] = await Promise.all([
4748
getPage(project, title, options),
4849
getUserId(options),
4950
getProjectId(project, options),
5051
]);
51-
if (isErr(pageRes)) return pageRes;
52-
if (isErr(userRes)) return userRes;
53-
if (isErr(projectRes)) return projectRes;
54-
return createOk({
55-
...unwrapOk(pageRes),
56-
projectId: unwrapOk(projectRes),
57-
userId: unwrapOk(userRes),
58-
});
52+
53+
if (!pageRes.ok || !userRes.ok || !projectRes.ok) {
54+
const status = pageRes.ok
55+
? (userRes.ok ? projectRes.status : userRes.status)
56+
: pageRes.status;
57+
const errorStatus = status === 404
58+
? 404
59+
: (status === 408 ? 408 : (status === 500 ? 500 : 400));
60+
return createErrorResponse(errorStatus, {
61+
message: "Failed to fetch required data",
62+
} as PullError);
63+
}
64+
65+
const page = await pageRes.json() as Page;
66+
const userId = await userRes.clone().text();
67+
const projectId = await projectRes.clone().text();
68+
69+
const metadata: PushMetadata = {
70+
...page,
71+
projectId,
72+
userId,
73+
};
74+
return createSuccessResponse(metadata);
5975
};
6076
// TODO: 編集不可なページはStream購読だけ提供する
6177

6278
/** cached user ID */
6379
let userId: string | undefined;
6480
const getUserId = async (init?: BaseOptions): Promise<
65-
Result<
66-
string,
67-
Omit<NotLoggedInError, "details"> | NetworkError | AbortError | HTTPError
81+
TargetedResponse<
82+
200 | 400 | 404 | 408 | 500,
83+
| string
84+
| Omit<NotLoggedInError, "details">
85+
| NetworkError
86+
| AbortError
87+
| HTTPError
6888
>
6989
> => {
70-
if (userId) return createOk(userId);
90+
if (userId) {
91+
return createSuccessResponse(userId);
92+
}
7193

7294
const result = await getProfile(init);
73-
if (isErr(result)) return result;
95+
if (!result.ok) {
96+
return createErrorResponse(400, {
97+
name: "NotLoggedInError",
98+
message: "Failed to fetch profile",
99+
});
100+
}
74101

75-
const user = unwrapOk(result);
102+
const user = await result.json() as MemberUser | GuestUser;
76103
if ("id" in user) {
77104
userId = user.id;
78-
return createOk(user.id);
105+
return createSuccessResponse(user.id);
79106
}
80-
return createErr({
107+
return createErrorResponse(400, {
81108
name: "NotLoggedInError",
82109
message: "This script cannot be used without login",
83110
});
@@ -89,8 +116,9 @@ export const getProjectId = async (
89116
project: string,
90117
options?: BaseOptions,
91118
): Promise<
92-
Result<
93-
string,
119+
TargetedResponse<
120+
200 | 400 | 404 | 408 | 500,
121+
| string
94122
| NotFoundError
95123
| NotLoggedInError
96124
| NotMemberError
@@ -100,13 +128,21 @@ export const getProjectId = async (
100128
>
101129
> => {
102130
const cachedId = projectMap.get(project);
103-
if (cachedId) return createOk(cachedId);
131+
if (cachedId) {
132+
return createSuccessResponse(cachedId);
133+
}
134+
135+
const result = await getProject(project, options);
136+
if (!result.ok) {
137+
return createErrorResponse(404, {
138+
name: "NotFoundError",
139+
message: `Project ${project} not found`,
140+
project,
141+
});
142+
}
104143

105-
return mapForResult(
106-
await getProject(project, options),
107-
({ id }) => {
108-
projectMap.set(project, id);
109-
return id;
110-
},
111-
);
144+
const data = await result.json();
145+
const id = (data as { id: string }).id;
146+
projectMap.set(project, id);
147+
return createSuccessResponse(id);
112148
};

browser/websocket/push.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ export const push = async (
115115
}
116116
const socket = unwrapOk(result);
117117
const pullResult = await pull(project, title);
118-
if (isErr(pullResult)) return pullResult;
119-
let metadata = unwrapOk(pullResult);
118+
if (!pullResult.ok) {
119+
const error = await pullResult.json() as PushError;
120+
return createErr(error);
121+
}
122+
let metadata = await pullResult.json() as PushMetadata;
120123

121124
try {
122125
let attempts = 0;
@@ -167,8 +170,11 @@ export const push = async (
167170
if (name === "NotFastForwardError") {
168171
await delay(1000);
169172
const pullResult = await pull(project, title);
170-
if (isErr(pullResult)) return pullResult;
171-
metadata = unwrapOk(pullResult);
173+
if (!pullResult.ok) {
174+
const error = await pullResult.json() as PushError;
175+
return createErr(error);
176+
}
177+
metadata = await pullResult.json() as PushMetadata;
172178
}
173179
reason = name;
174180
// go back to the diff loop

deno.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@std/async": "jsr:@std/async@1",
1919
"@std/encoding": "jsr:@std/encoding@1",
2020
"@std/json": "jsr:@std/json@^1.0.0",
21+
"@std/testing": "jsr:@std/testing@^1.0.8",
2122
"@std/testing/snapshot": "jsr:@std/testing@1/snapshot",
2223
"@takker/md5": "jsr:@takker/md5@0.1",
2324
"@takker/onp": "./vendor/raw.githubusercontent.com/takker99/onp/0.0.1/mod.ts",

deno.lock

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

0 commit comments

Comments
 (0)