From 2298e9f19afcf5a0788763f7e75a0b4411dd38c4 Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Sun, 23 Feb 2025 16:41:00 +0900 Subject: [PATCH 1/7] =?UTF-8?q?chore:=20errorToMessage=E3=81=AE=E6=96=87?= =?UTF-8?q?=E9=9D=A2=E3=82=92=E3=81=84=E3=81=84=E6=84=9F=E3=81=98=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=80=81=E3=83=86=E3=82=B9=E3=83=88=E3=82=82=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/errorHelper.ts | 56 +++++++++++++++++++++++---- tests/unit/lib/errorHelper.spec.ts | 61 ++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 tests/unit/lib/errorHelper.spec.ts diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 76fc0f1f80..4162139f04 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -9,15 +9,55 @@ export const ensureNotNullish = ( return value; }; -/** エラーからエラー文を作る */ +/** エラーからエラー文を作る。長い場合は後ろを切る。 */ export const errorToMessage = (e: unknown): string => { + if (e instanceof AggregateError) { + const messageLines = []; + if (e.message) { + messageLines.push(e.message); + } + for (const error of e.errors) { + messageLines.push(errorToMessage(error)); + } + return trim(messageLines.join("\n")); + } + if (e instanceof Error) { - return `${e.toString()}: ${e.message}`; - } else if (typeof e === "string") { - return `String Error: ${e}`; - } else if (typeof e === "object" && e != undefined) { - return `Object Error: ${JSON.stringify(e).slice(0, 100)}`; - } else { - return `Unknown Error: ${String(e)}`; + let message = e.name !== "Error" ? `${e.name}: ${e.message}` : e.message; + if (e.cause) { + message += `\n${errorToMessage(e.cause)}`; + } + return trim(message); + } + + if (typeof e === "string") { + return trim(`Unknown Error: ${e}`); + } + + if (typeof e === "object" && e != undefined) { + return trim(`Unknown Error: ${JSON.stringify(e)}`); + } + + return trim(`Unknown Error: ${String(e)}`); + + function trim(str: string) { + return trimLongString(trimLines(str)); + } + + function trimLines(str: string) { + // 15行以上ある場合は15行までにする + const lines = str.split("\n"); + if (lines.length > 15) { + return lines.slice(0, 15 - 1).join("\n") + "\n..."; + } + return str; + } + + function trimLongString(str: string) { + // 300文字以上ある場合は300文字までにする + if (str.length > 300) { + return str.slice(0, 300 - 3) + "..."; + } + return str; } }; diff --git a/tests/unit/lib/errorHelper.spec.ts b/tests/unit/lib/errorHelper.spec.ts new file mode 100644 index 0000000000..c6166357bd --- /dev/null +++ b/tests/unit/lib/errorHelper.spec.ts @@ -0,0 +1,61 @@ +import { describe, it, expect } from "vitest"; +import { errorToMessage } from "@/helpers/errorHelper"; + +describe("errorToMessage", () => { + it("Errorインスタンス", () => { + const input = new Error("error instance"); + const expected = "error instance"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("SyntaxErrorインスタンス", () => { + const input = new SyntaxError("syntax error instance"); + const expected = "SyntaxError: syntax error instance"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("自作エラーインスタンス", () => { + class CustomError extends Error { + constructor(message: string) { + super(message); + this.name = "CustomError"; + } + } + const input = new CustomError("custom error instance"); + const expected = "CustomError: custom error instance"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("AggregateErrorインスタンス", () => { + const input = new AggregateError( + [new Error("error1"), new Error("error2")], + "aggregate error", + ); + const expected = "aggregate error\nerror1\nerror2"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("cause付きエラーインスタンス", () => { + const input = new Error("error instance", { cause: new Error("cause") }); + const expected = "error instance\ncause"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("文字列エラー", () => { + const input = "string error"; + const expected = "Unknown Error: string error"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("オブジェクトエラー", () => { + const input = { key: "value" }; + const expected = 'Unknown Error: {"key":"value"}'; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("不明なエラー", () => { + const input = undefined; + const expected = "Unknown Error: undefined"; + expect(errorToMessage(input)).toEqual(expected); + }); +}); From fa1e4622c8b92da9d452b3933cc7eb386e425a17 Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Mon, 24 Feb 2025 21:25:11 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=E3=81=A8=E3=82=8A=E3=81=82=E3=81=88?= =?UTF-8?q?=E3=81=9A=E3=81=A7=E3=81=8D=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/errorHelper.ts | 86 ++++++++++++++++++++++-------- tests/unit/lib/errorHelper.spec.ts | 55 +++++++++++++++---- 2 files changed, 111 insertions(+), 30 deletions(-) diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 4162139f04..0547497787 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -9,36 +9,80 @@ export const ensureNotNullish = ( return value; }; -/** エラーからエラー文を作る。長い場合は後ろを切る。 */ +/** + * ユーザーに表示するメッセージを持つエラー。 + * errorToMessageに渡すとユーザー向けのメッセージとして扱われる。 + */ +export class DisplayableError extends Error { + constructor(userFriendlyMessage: string, { cause }: { cause?: Error } = {}) { + super(userFriendlyMessage, { cause }); + this.name = "DisplayableError"; + } +} + +/** + * 例外からエラーメッセージを作る。 + * DisplayableErrorのメッセージはユーザー向けのメッセージとして扱う。 + * それ以外の例外のメッセージは内部エラーメッセージとして扱う。 + * causeやAggregateErrorの場合は再帰的に処理する。 + * 再帰的に処理する際、一度DisplayableError以外の例外を処理した後は内部エラーメッセージとして扱う。 + * 長い場合は後ろを切る。 + */ export const errorToMessage = (e: unknown): string => { - if (e instanceof AggregateError) { - const messageLines = []; - if (e.message) { + return trim(errorToMessageLines(e).join("\n")); + + function errorToMessageLines( + e: unknown, + { isInner }: { isInner?: boolean } = {}, + ): string[] { + const messageLines: string[] = []; + + if (e instanceof DisplayableError) { messageLines.push(e.message); + if (e.cause) { + messageLines.push(...errorToMessageLines(e.cause, { isInner })); + } + return messageLines; } - for (const error of e.errors) { - messageLines.push(errorToMessage(error)); + + if (!isInner) { + messageLines.push("(内部エラーメッセージ)"); + isInner = true; } - return trim(messageLines.join("\n")); - } - if (e instanceof Error) { - let message = e.name !== "Error" ? `${e.name}: ${e.message}` : e.message; - if (e.cause) { - message += `\n${errorToMessage(e.cause)}`; + if (e instanceof AggregateError) { + if (e.message) { + messageLines.push(e.message); + } + for (const error of e.errors) { + messageLines.push(...errorToMessageLines(error, { isInner })); + } + return messageLines; } - return trim(message); - } - if (typeof e === "string") { - return trim(`Unknown Error: ${e}`); - } + if (e instanceof Error) { + messageLines.push( + e.name !== "Error" ? `${e.name}: ${e.message}` : e.message, + ); + if (e.cause) { + messageLines.push(...errorToMessageLines(e.cause, { isInner })); + } + return messageLines; + } - if (typeof e === "object" && e != undefined) { - return trim(`Unknown Error: ${JSON.stringify(e)}`); - } + if (typeof e === "string") { + messageLines.push(`Unknown Error: ${e}`); + return messageLines; + } - return trim(`Unknown Error: ${String(e)}`); + if (typeof e === "object" && e != undefined) { + messageLines.push(`Unknown Error: ${JSON.stringify(e)}`); + return messageLines; + } + + messageLines.push(`Unknown Error: ${String(e)}`); + return messageLines; + } function trim(str: string) { return trimLongString(trimLines(str)); diff --git a/tests/unit/lib/errorHelper.spec.ts b/tests/unit/lib/errorHelper.spec.ts index c6166357bd..7f2e61a313 100644 --- a/tests/unit/lib/errorHelper.spec.ts +++ b/tests/unit/lib/errorHelper.spec.ts @@ -1,16 +1,17 @@ import { describe, it, expect } from "vitest"; -import { errorToMessage } from "@/helpers/errorHelper"; +import { DisplayableError, errorToMessage } from "@/helpers/errorHelper"; describe("errorToMessage", () => { it("Errorインスタンス", () => { const input = new Error("error instance"); - const expected = "error instance"; + const expected = "(内部エラーメッセージ)\nerror instance"; expect(errorToMessage(input)).toEqual(expected); }); it("SyntaxErrorインスタンス", () => { const input = new SyntaxError("syntax error instance"); - const expected = "SyntaxError: syntax error instance"; + const expected = + "(内部エラーメッセージ)\nSyntaxError: syntax error instance"; expect(errorToMessage(input)).toEqual(expected); }); @@ -22,7 +23,8 @@ describe("errorToMessage", () => { } } const input = new CustomError("custom error instance"); - const expected = "CustomError: custom error instance"; + const expected = + "(内部エラーメッセージ)\nCustomError: custom error instance"; expect(errorToMessage(input)).toEqual(expected); }); @@ -31,31 +33,66 @@ describe("errorToMessage", () => { [new Error("error1"), new Error("error2")], "aggregate error", ); - const expected = "aggregate error\nerror1\nerror2"; + const expected = + "(内部エラーメッセージ)\naggregate error\nerror1\nerror2"; expect(errorToMessage(input)).toEqual(expected); }); it("cause付きエラーインスタンス", () => { const input = new Error("error instance", { cause: new Error("cause") }); - const expected = "error instance\ncause"; + const expected = "(内部エラーメッセージ)\nerror instance\ncause"; expect(errorToMessage(input)).toEqual(expected); }); it("文字列エラー", () => { const input = "string error"; - const expected = "Unknown Error: string error"; + const expected = "(内部エラーメッセージ)\nUnknown Error: string error"; expect(errorToMessage(input)).toEqual(expected); }); it("オブジェクトエラー", () => { const input = { key: "value" }; - const expected = 'Unknown Error: {"key":"value"}'; + const expected = '(内部エラーメッセージ)\nUnknown Error: {"key":"value"}'; expect(errorToMessage(input)).toEqual(expected); }); it("不明なエラー", () => { const input = undefined; - const expected = "Unknown Error: undefined"; + const expected = "(内部エラーメッセージ)\nUnknown Error: undefined"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("DisplayableErrorインスタンス", () => { + const input = new DisplayableError("displayable error instance"); + const expected = "displayable error instance"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("DisplayableError -> Error", () => { + const input = new DisplayableError("displayable error instance", { + cause: new Error("cause"), + }); + const expected = + "displayable error instance\n(内部エラーメッセージ)\ncause"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("DisplayableError -> DisplayableError", () => { + const input = new DisplayableError("displayable error instance", { + cause: new DisplayableError("displayable cause"), + }); + const expected = "displayable error instance\ndisplayable cause"; + expect(errorToMessage(input)).toEqual(expected); + }); + + it("DisplayableError -> Error -> DisplayableError", () => { + const input = new DisplayableError("displayable error instance", { + cause: new Error("cause", { + cause: new DisplayableError("displayable cause"), + }), + }); + const expected = + "displayable error instance\n(内部エラーメッセージ)\ncause\ndisplayable cause"; expect(errorToMessage(input)).toEqual(expected); }); }); From aa988c7dfe5d9ae9a24f969a6bf2214a51d29f5d Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Mon, 24 Feb 2025 22:25:33 +0900 Subject: [PATCH 3/7] refactor: flattenErrors --- src/helpers/errorHelper.ts | 75 ++++++++++++++---------------- tests/unit/lib/errorHelper.spec.ts | 2 +- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 0547497787..36d6569980 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -29,58 +29,55 @@ export class DisplayableError extends Error { * 長い場合は後ろを切る。 */ export const errorToMessage = (e: unknown): string => { - return trim(errorToMessageLines(e).join("\n")); + const errors = flattenErrors(e); + const messages = toMessageLines(errors); + return trim(messages.join("\n")); - function errorToMessageLines( - e: unknown, - { isInner }: { isInner?: boolean } = {}, - ): string[] { - const messageLines: string[] = []; - - if (e instanceof DisplayableError) { - messageLines.push(e.message); - if (e.cause) { - messageLines.push(...errorToMessageLines(e.cause, { isInner })); - } - return messageLines; + function flattenErrors(e: unknown): unknown[] { + if (e instanceof AggregateError) { + return [e, ...e.errors.flatMap(flattenErrors)]; } - - if (!isInner) { - messageLines.push("(内部エラーメッセージ)"); - isInner = true; + if (e instanceof Error) { + return [e, ...(e.cause ? flattenErrors(e.cause) : [])]; } + return [e]; + } - if (e instanceof AggregateError) { - if (e.message) { + function toMessageLines(errors: unknown[]): string[] { + const messageLines: string[] = []; + + let isInner = false; + for (const e of errors) { + if (e instanceof DisplayableError) { messageLines.push(e.message); + continue; } - for (const error of e.errors) { - messageLines.push(...errorToMessageLines(error, { isInner })); + + if (!isInner) { + messageLines.push("(内部エラーメッセージ)"); + isInner = true; } - return messageLines; - } - if (e instanceof Error) { - messageLines.push( - e.name !== "Error" ? `${e.name}: ${e.message}` : e.message, - ); - if (e.cause) { - messageLines.push(...errorToMessageLines(e.cause, { isInner })); + if (e instanceof Error) { + messageLines.push( + e.name !== "Error" ? `${e.name}: ${e.message}` : e.message, + ); + continue; } - return messageLines; - } - if (typeof e === "string") { - messageLines.push(`Unknown Error: ${e}`); - return messageLines; - } + if (typeof e === "string") { + messageLines.push(`Unknown Error: ${e}`); + continue; + } + + if (typeof e === "object" && e != undefined) { + messageLines.push(`Unknown Error: ${JSON.stringify(e)}`); + continue; + } - if (typeof e === "object" && e != undefined) { - messageLines.push(`Unknown Error: ${JSON.stringify(e)}`); - return messageLines; + messageLines.push(`Unknown Error: ${String(e)}`); } - messageLines.push(`Unknown Error: ${String(e)}`); return messageLines; } diff --git a/tests/unit/lib/errorHelper.spec.ts b/tests/unit/lib/errorHelper.spec.ts index 7f2e61a313..3c7164f2b7 100644 --- a/tests/unit/lib/errorHelper.spec.ts +++ b/tests/unit/lib/errorHelper.spec.ts @@ -34,7 +34,7 @@ describe("errorToMessage", () => { "aggregate error", ); const expected = - "(内部エラーメッセージ)\naggregate error\nerror1\nerror2"; + "(内部エラーメッセージ)\nAggregateError: aggregate error\nerror1\nerror2"; expect(errorToMessage(input)).toEqual(expected); }); From 4850e4c4a558e5147d4c697b92496fc434db6595 Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Mon, 24 Feb 2025 23:05:19 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20errorToMessages=E9=96=A2=E6=95=B0?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/errorHelper.ts | 81 +++++++++++++++++++----------- tests/unit/lib/errorHelper.spec.ts | 2 +- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 36d6569980..153c1a786e 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -1,3 +1,5 @@ +import { UnreachableError } from "@/type/utility"; + /** 入力がnullかundefinedの場合エラーを投げ、それ以外の場合は入力をそのまま返す */ export const ensureNotNullish = ( value: T | null | undefined, @@ -11,7 +13,7 @@ export const ensureNotNullish = ( /** * ユーザーに表示するメッセージを持つエラー。 - * errorToMessageに渡すとユーザー向けのメッセージとして扱われる。 + * {@link errorToMessages}でユーザー向けのメッセージとして扱われる。 */ export class DisplayableError extends Error { constructor(userFriendlyMessage: string, { cause }: { cause?: Error } = {}) { @@ -21,17 +23,17 @@ export class DisplayableError extends Error { } /** - * 例外からエラーメッセージを作る。 - * DisplayableErrorのメッセージはユーザー向けのメッセージとして扱う。 - * それ以外の例外のメッセージは内部エラーメッセージとして扱う。 + * 例外からユーザー向けのエラーメッセージと内部向けのエラーメッセージを作る。 + * DisplayableErrorのメッセージはユーザー向けとして扱う。 + * それ以外の例外のメッセージは内部向けとして扱う。 * causeやAggregateErrorの場合は再帰的に処理する。 - * 再帰的に処理する際、一度DisplayableError以外の例外を処理した後は内部エラーメッセージとして扱う。 - * 長い場合は後ろを切る。 + * 再帰的に処理する際、一度DisplayableError以外の例外を処理した後は内部向けとして扱う。 */ -export const errorToMessage = (e: unknown): string => { +export const errorToMessages = ( + e: unknown, +): { displayable: string[]; internal: string[] } => { const errors = flattenErrors(e); - const messages = toMessageLines(errors); - return trim(messages.join("\n")); + return toMessageLines(errors); function flattenErrors(e: unknown): unknown[] { if (e instanceof AggregateError) { @@ -43,43 +45,66 @@ export const errorToMessage = (e: unknown): string => { return [e]; } - function toMessageLines(errors: unknown[]): string[] { - const messageLines: string[] = []; - - let isInner = false; - for (const e of errors) { - if (e instanceof DisplayableError) { - messageLines.push(e.message); - continue; - } + function toMessageLines(errors: unknown[]): { + displayable: string[]; + internal: string[]; + } { + let displayableCount = errors.findIndex( + (e) => !(e instanceof DisplayableError), + ); + if (displayableCount === -1) { + displayableCount = errors.length; + } - if (!isInner) { - messageLines.push("(内部エラーメッセージ)"); - isInner = true; + const displayable: string[] = []; + for (const e of errors.slice(0, displayableCount)) { + if (!(e instanceof DisplayableError)) { + throw new UnreachableError(); } + displayable.push(e.message); + } + const internal: string[] = []; + for (const e of errors.slice(displayableCount)) { if (e instanceof Error) { - messageLines.push( - e.name !== "Error" ? `${e.name}: ${e.message}` : e.message, - ); + let message = ""; + if (!["Error", "AggregateError", "DisplayableError"].includes(e.name)) { + message += `${e.name}: `; + } + message += e.message; + internal.push(message); continue; } if (typeof e === "string") { - messageLines.push(`Unknown Error: ${e}`); + internal.push(`Unknown Error: ${e}`); continue; } if (typeof e === "object" && e != undefined) { - messageLines.push(`Unknown Error: ${JSON.stringify(e)}`); + internal.push(`Unknown Error: ${JSON.stringify(e)}`); continue; } - messageLines.push(`Unknown Error: ${String(e)}`); + internal.push(`Unknown Error: ${String(e)}`); } - return messageLines; + return { displayable, internal }; } +}; + +/** + * 例外からエラーメッセージを作る。 + * {@link errorToMessages}の結果を結合して返す。 + * 長い場合は後ろを切る。 + */ +export const errorToMessage = (e: unknown): string => { + const { displayable, internal } = errorToMessages(e); + const messages = [...displayable]; + if (internal.length > 0) { + messages.push("(内部エラーメッセージ)", ...internal); + } + return trim(messages.join("\n")); function trim(str: string) { return trimLongString(trimLines(str)); diff --git a/tests/unit/lib/errorHelper.spec.ts b/tests/unit/lib/errorHelper.spec.ts index 3c7164f2b7..7f2e61a313 100644 --- a/tests/unit/lib/errorHelper.spec.ts +++ b/tests/unit/lib/errorHelper.spec.ts @@ -34,7 +34,7 @@ describe("errorToMessage", () => { "aggregate error", ); const expected = - "(内部エラーメッセージ)\nAggregateError: aggregate error\nerror1\nerror2"; + "(内部エラーメッセージ)\naggregate error\nerror1\nerror2"; expect(errorToMessage(input)).toEqual(expected); }); From 057da953277ef2fb181d61bf20baecdf43287e65 Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Mon, 24 Feb 2025 23:14:04 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20errorToMessages=E9=96=A2?= =?UTF-8?q?=E6=95=B0=E3=82=92=E5=88=86=E5=89=B2=E3=81=97=E3=80=81=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/errorHelper.ts | 40 ++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 153c1a786e..6fe414cefb 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -33,7 +33,11 @@ export const errorToMessages = ( e: unknown, ): { displayable: string[]; internal: string[] } => { const errors = flattenErrors(e); - return toMessageLines(errors); + const { displayable, internal } = splitErrors(errors); + return { + displayable: toMessages(displayable), + internal: toMessages(internal), + }; function flattenErrors(e: unknown): unknown[] { if (e instanceof AggregateError) { @@ -45,9 +49,9 @@ export const errorToMessages = ( return [e]; } - function toMessageLines(errors: unknown[]): { - displayable: string[]; - internal: string[]; + function splitErrors(errors: unknown[]): { + displayable: unknown[]; + internal: unknown[]; } { let displayableCount = errors.findIndex( (e) => !(e instanceof DisplayableError), @@ -56,40 +60,38 @@ export const errorToMessages = ( displayableCount = errors.length; } - const displayable: string[] = []; - for (const e of errors.slice(0, displayableCount)) { - if (!(e instanceof DisplayableError)) { - throw new UnreachableError(); - } - displayable.push(e.message); - } + return { + displayable: errors.slice(0, displayableCount), + internal: errors.slice(displayableCount), + }; + } - const internal: string[] = []; - for (const e of errors.slice(displayableCount)) { + function toMessages(errors: unknown[]): string[] { + const messages: string[] = []; + for (const e of errors) { if (e instanceof Error) { let message = ""; if (!["Error", "AggregateError", "DisplayableError"].includes(e.name)) { message += `${e.name}: `; } message += e.message; - internal.push(message); + messages.push(message); continue; } if (typeof e === "string") { - internal.push(`Unknown Error: ${e}`); + messages.push(`Unknown Error: ${e}`); continue; } if (typeof e === "object" && e != undefined) { - internal.push(`Unknown Error: ${JSON.stringify(e)}`); + messages.push(`Unknown Error: ${JSON.stringify(e)}`); continue; } - internal.push(`Unknown Error: ${String(e)}`); + messages.push(`Unknown Error: ${String(e)}`); } - - return { displayable, internal }; + return messages; } }; From 4a4cb101c8516eb8908ac0de92f4e0ffcfd6c12d Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Mon, 24 Feb 2025 23:17:02 +0900 Subject: [PATCH 6/7] =?UTF-8?q?refactor:=20=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/errorHelper.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 6fe414cefb..8090f56e73 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -53,16 +53,15 @@ export const errorToMessages = ( displayable: unknown[]; internal: unknown[]; } { - let displayableCount = errors.findIndex( - (e) => !(e instanceof DisplayableError), + const firstInternalErrorIndex = errors.findIndex( + (error) => !(error instanceof DisplayableError), ); - if (displayableCount === -1) { - displayableCount = errors.length; - } + const splitIndex = + firstInternalErrorIndex === -1 ? errors.length : firstInternalErrorIndex; return { - displayable: errors.slice(0, displayableCount), - internal: errors.slice(displayableCount), + displayable: errors.slice(0, splitIndex), + internal: errors.slice(splitIndex), }; } From 44afe4601fc939ac89d08a89cd477741f59e3114 Mon Sep 17 00:00:00 2001 From: Hiroshiba Kazuyuki Date: Mon, 24 Feb 2025 23:21:07 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=E4=B8=8D=E8=A6=81=E3=81=AA=E9=96=A2?= =?UTF-8?q?=E6=95=B0=E3=82=92=E9=99=A4=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/errorHelper.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/helpers/errorHelper.ts b/src/helpers/errorHelper.ts index 8090f56e73..87f5d0652a 100644 --- a/src/helpers/errorHelper.ts +++ b/src/helpers/errorHelper.ts @@ -1,5 +1,3 @@ -import { UnreachableError } from "@/type/utility"; - /** 入力がnullかundefinedの場合エラーを投げ、それ以外の場合は入力をそのまま返す */ export const ensureNotNullish = ( value: T | null | undefined, @@ -40,13 +38,14 @@ export const errorToMessages = ( }; function flattenErrors(e: unknown): unknown[] { + const errors = [e]; if (e instanceof AggregateError) { - return [e, ...e.errors.flatMap(flattenErrors)]; + errors.push(...e.errors.flatMap(flattenErrors)); } - if (e instanceof Error) { - return [e, ...(e.cause ? flattenErrors(e.cause) : [])]; + if (e instanceof Error && e.cause) { + errors.push(...flattenErrors(e.cause)); } - return [e]; + return errors; } function splitErrors(errors: unknown[]): {