Skip to content

Commit c8c16fd

Browse files
authored
Merge pull request #40 from increments/improve-error-message
Improve error messages
2 parents af83aef + 9468550 commit c8c16fd

File tree

8 files changed

+183
-21
lines changed

8 files changed

+183
-21
lines changed

src/client/pages/items/show.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export const ItemsShow = () => {
124124
<MaterialSymbol fill={true} css={exclamationIconStyle}>
125125
error
126126
</MaterialSymbol>
127-
<div css={errorMessageBodyStyle}>{errorMessage}</div>
127+
<div>{errorMessage}</div>
128128
</p>
129129
))}
130130
</div>
@@ -184,7 +184,3 @@ const errorStyle = css({
184184
display: "flex",
185185
marginTop: getSpace(3 / 2),
186186
});
187-
188-
const errorMessageBodyStyle = css({
189-
whiteSpace: "pre",
190-
});

src/commands/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { handleError } from "../lib/error-handler";
12
import { packageUpdateNotice } from "../lib/package-update-notice";
23
import { help, helpText } from "./help";
34
import { init } from "./init";
@@ -38,5 +39,11 @@ export const exec = async (commandName: string, commandArgs: string[]) => {
3839
console.log(updateMessage);
3940
}
4041

41-
commands[commandName](commandArgs);
42+
try {
43+
await commands[commandName](commandArgs);
44+
} catch (err) {
45+
console.error(err);
46+
await handleError(err as Error);
47+
process.exit(1);
48+
}
4249
};

src/commands/publish.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ export const publish = async (argv: string[]) => {
6565
return acc;
6666
}, [] as { name: string; errors: string[] }[]);
6767
if (invalidItemMessages.length > 0) {
68-
console.error("Validation error:");
68+
const chalk = (await import("chalk")).default;
6969
invalidItemMessages.forEach((msg) => {
70-
console.error(msg.name, msg.errors);
70+
msg.errors.forEach((err) => {
71+
const errorName = chalk.red.bold(msg.name + ":");
72+
const errorDescription = chalk.red(err);
73+
console.error(`${errorName} ${errorDescription}`);
74+
});
7175
});
76+
7277
process.exit(1);
7378
}
7479

src/lib/check-frontmatter-type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const checkOrganizationUrlName: CheckType = {
6565

6666
const checkSlide: CheckType = {
6767
getMessage: () =>
68-
"slideの設定はtrue/falseで入力してください\n\n【破壊的な変更がありました】\n詳しくは以下のリリースをご確認ください\nhttps://github.com/increments/qiita-cli/releases/tag/v0.5.0",
68+
"slideの設定はtrue/falseで入力してください破壊的な変更がありました。詳しくはリリースをご確認ください https://github.com/increments/qiita-cli/releases/tag/v0.5.0",
6969
isValid: ({ slide }) => {
7070
return typeof slide === "boolean";
7171
},

src/lib/error-handler.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {
2+
QiitaBadRequestError,
3+
QiitaFetchError,
4+
QiitaForbiddenError,
5+
QiitaInternalServerError,
6+
QiitaNotFoundError,
7+
QiitaRateLimitError,
8+
QiitaUnauthorizedError,
9+
QiitaUnknownError,
10+
} from "../qiita-api";
11+
12+
export const handleError = async (error: Error) => {
13+
const chalk = (await import("chalk")).default;
14+
15+
switch (error.name) {
16+
// Qiita API
17+
case QiitaFetchError.name:
18+
console.error(
19+
chalk.red.bold(
20+
"Qiita APIへのリクエストでネットワークエラーが発生しました"
21+
)
22+
);
23+
console.error(
24+
chalk.red(" インターネットに接続されているかご確認ください")
25+
);
26+
break;
27+
case QiitaBadRequestError.name:
28+
console.error(chalk.red.bold("Qiita APIへのリクエストに失敗しました"));
29+
console.error(chalk.red(" 記事ファイルに不備がないかご確認ください"));
30+
break;
31+
case QiitaUnauthorizedError.name:
32+
console.error(chalk.red.bold("Qiitaの認証に失敗しました"));
33+
console.error(
34+
chalk.red(" loginコマンドでQiitaにログインしているかご確認ください")
35+
);
36+
console.error(
37+
chalk.red(" Qiitaのアクセストークンが正しいかご確認ください")
38+
);
39+
break;
40+
case QiitaForbiddenError.name:
41+
console.error(chalk.red.bold("Qiita APIへのリクエストに失敗しました"));
42+
console.error(
43+
chalk.red(" Qiitaのアクセストークンが正しいかご確認ください")
44+
);
45+
console.error(chalk.red(""));
46+
break;
47+
case QiitaNotFoundError.name:
48+
console.error(chalk.red.bold("記事が見つかりませんでした"));
49+
console.error(
50+
chalk.red(" Qiita上で記事が削除されていないかご確認ください")
51+
);
52+
break;
53+
case QiitaRateLimitError.name:
54+
console.error(chalk.red.bold("Qiita APIのレートリミットに達しました"));
55+
console.error(chalk.red(" しばらく時間を置いてから再度お試しください"));
56+
break;
57+
case QiitaInternalServerError.name:
58+
console.error(chalk.red.bold("Qiitaのサーバーでエラーが発生しました"));
59+
console.error(chalk.red(" しばらく時間を置いてから再度お試しください"));
60+
break;
61+
case QiitaUnknownError.name:
62+
console.error(
63+
chalk.red.bold("Qiita APIへのリクエストで不明なエラーが発生しました")
64+
);
65+
console.error(
66+
chalk.red(
67+
" バグの可能性がある場合は、Qiita Discussionsよりご報告いただけると幸いです"
68+
)
69+
);
70+
console.error(
71+
chalk.red(" https://github.com/increments/qiita-discussions")
72+
);
73+
break;
74+
75+
default:
76+
console.error(chalk.red.bold(`エラーが発生しました (${error.message})`));
77+
console.error(
78+
chalk.red(
79+
" バグの可能性がある場合は、Qiita Discussionsよりご報告いただけると幸いです"
80+
)
81+
);
82+
console.error(
83+
chalk.red(" https://github.com/increments/qiita-discussions")
84+
);
85+
}
86+
};

src/qiita-api/errors.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
export class QiitaFetchError extends Error {
2+
constructor(message: string) {
3+
super(message);
4+
this.name = "QiitaFetchError";
5+
}
6+
}
7+
8+
export class QiitaBadRequestError extends Error {
9+
constructor(message: string) {
10+
super(message);
11+
this.name = "QiitaBadRequestError";
12+
}
13+
}
14+
15+
export class QiitaUnauthorizedError extends Error {
16+
constructor(message: string) {
17+
super(message);
18+
this.name = "QiitaUnauthorizedError";
19+
}
20+
}
21+
22+
export class QiitaForbiddenError extends Error {
23+
constructor(message: string) {
24+
super(message);
25+
this.name = "QiitaForbiddenError";
26+
}
27+
}
28+
29+
export class QiitaNotFoundError extends Error {
30+
constructor(message: string) {
31+
super(message);
32+
this.name = "QiitaNotFoundError";
33+
}
34+
}
35+
36+
export class QiitaRateLimitError extends Error {
37+
constructor(message: string) {
38+
super(message);
39+
this.name = "QiitaRateLimitError";
40+
}
41+
}
42+
43+
export class QiitaInternalServerError extends Error {
44+
constructor(message: string) {
45+
super(message);
46+
this.name = "QiitaInternalServerError";
47+
}
48+
}
49+
50+
export class QiitaUnknownError extends Error {
51+
constructor(message: string) {
52+
super(message);
53+
this.name = "QiitaUnknownError";
54+
}
55+
}

src/qiita-api/index.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import { URL, URLSearchParams } from "node:url";
2+
import {
3+
QiitaBadRequestError,
4+
QiitaFetchError,
5+
QiitaForbiddenError,
6+
QiitaInternalServerError,
7+
QiitaNotFoundError,
8+
QiitaRateLimitError,
9+
QiitaUnauthorizedError,
10+
QiitaUnknownError,
11+
} from "./errors";
212
import { qiitaApiDebugger } from "./lib/debugger";
313

14+
export * from "./errors";
15+
416
export interface Item {
517
body: string;
618
id: string;
@@ -65,7 +77,7 @@ export class QiitaApi {
6577
});
6678
} catch (err) {
6779
console.error(err);
68-
throw new Error("NetworkError");
80+
throw new QiitaFetchError((err as Error).message);
6981
}
7082

7183
if (response.ok) {
@@ -78,8 +90,8 @@ export class QiitaApi {
7890
}
7991
}
8092

93+
const responseBody = await response.text();
8194
if (qiitaApiDebugger.enabled) {
82-
const responseBody = await response.text();
8395
qiitaApiDebugger(
8496
"request failed",
8597
JSON.stringify({
@@ -89,21 +101,22 @@ export class QiitaApi {
89101
);
90102
}
91103

104+
const errorMessage = responseBody.slice(0, 100);
92105
switch (response.status) {
93106
case 400:
94-
throw new Error("QiitaBadRequestError");
107+
throw new QiitaBadRequestError(errorMessage);
95108
case 401:
96-
throw new Error("QiitaUnauthorizedError");
109+
throw new QiitaUnauthorizedError(errorMessage);
97110
case 403:
98-
throw new Error("QiitaForbiddenError");
111+
throw new QiitaForbiddenError(errorMessage);
99112
case 404:
100-
throw new Error("QiitaNotFoundError");
113+
throw new QiitaNotFoundError(errorMessage);
101114
case 429:
102-
throw new Error("QiitaRateLimitError");
115+
throw new QiitaRateLimitError(errorMessage);
103116
case 500:
104-
throw new Error("QiitaInternalServerError");
117+
throw new QiitaInternalServerError(errorMessage);
105118
default:
106-
throw new Error("QiitaUnknownError");
119+
throw new QiitaUnknownError(errorMessage);
107120
}
108121
}
109122

src/server/app.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ export async function startServer() {
3535
const port = userConfig.port;
3636
const host = "localhost";
3737

38-
return new Promise<Server>((resolve) => {
38+
return new Promise<Server>((resolve, reject) => {
3939
server
4040
.listen(port, host)
4141
.once("listening", () => {
4242
console.log(`Preview: http://${host}:${port}`);
4343

4444
resolve(server);
4545
})
46-
.once("error", () => {
47-
throw new Error("Failed to start server");
46+
.once("error", (err) => {
47+
reject(err);
4848
});
4949
});
5050
}

0 commit comments

Comments
 (0)