Skip to content

リクエストエラーからステータスコード・URL・原因を参照できるようにする - #109

Merged
Sinhalite merged 2 commits into
microcmsio:mainfrom
Sinhalite:codex/improve-request-errors
Sep 3, 2026
Merged

Sinhalite merged 2 commits into
microcmsio:mainfrom
Sinhalite:codex/improve-request-errors

Conversation

@Sinhalite

@Sinhalite Sinhalite commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

概要

microCMS APIへのリクエストが失敗した際に、原因調査に必要な情報をエラーオブジェクトから参照できるようにしました。

以下の要望への対応を目的としています。

  • HTTPエラーのステータスコードを構造化された値として取得したい
  • 複数のAPIリクエストのうち、どのURLへのリクエストが失敗したか特定したい
  • Node.jsのfetchなどが持つ、ネットワークエラーのcauseやエラーコードを確認したい

関連Issue:

変更内容

microCMS APIへのHTTP・ネットワークエラーに、以下のプロパティを追加しました。

プロパティ HTTPエラー ネットワークエラー
status HTTPステータスコード undefined
url リクエスト先URL リクエスト先URL
originalError undefined fetchが投げた元の値

あわせて、TypeScriptから安全にエラーを判定・参照できるよう、以下を公開しました。

  • MicroCMSRequestError 型
  • isMicroCMSRequestError type guard
try {
  await client.getList({ endpoint: 'blog' });
} catch (error) {
  if (isMicroCMSRequestError(error)) {
    console.log(error.status);
    console.log(error.url);
    console.log(error.originalError);
  }
}

Content APIとManagement APIのmicroCMS APIリクエストに適用しています。

後方互換性について

独自のエラーclassは導入せず、従来どおり生成した通常のErrorへ追加情報を付与しています。

追加プロパティは非列挙としているため、以下の既存挙動を維持します。

  • error instanceof Error
  • error.constructor === Error
  • error.name
  • error.message
  • error.toString()
  • console.log(error)の通常表示
  • Object.keys(error)
  • { ...error }
  • JSON.stringify(error)

既存のエラーメッセージ形式、リトライ条件・回数・間隔・ログ内容も変更していません。

また、HTTP成功後のJSONパースエラーなど、本変更の対象外となるエラーは従来どおりそのまま返します。

将来的な独自 Error class の検討

将来、Error の identity(constructor / name / instanceof)を変更する価値が、メジャーバージョンアップに見合うと判断した場合は、以下のような独自 Error class への移行を検討できます。

export class MicroCMSRequestError extends Error {
  constructor(
    message: string,
    options: MicroCMSRequestErrorOptions,
  ) {
    super(message);
    // status / url / originalError を保持する
  }
}

セキュリティへの配慮

リクエストURLにdraftKeyが含まれる場合は、その値だけを***へマスクします。他のクエリパラメータとURLは保持します。

以下の情報はエラーへ追加しません。

  • リクエストヘッダー
  • APIキー
  • リクエストボディ
  • Responseオブジェクト

originalErrorの形式はNode.js、ブラウザ、Edge Runtimeなどの実行環境によって異なるため、SDKとして具体的な形式は保証しません。

確認

  • npm test -- --runInBand
    • 65件成功
    • 既存の10件はskip
  • npm run typecheck
  • npm run lint
  • npm run format
  • npm run build
  • ダミーAPIキーによる401レスポンスで、status、マスク済みurl、既存のconsole.log(error)表示を確認

Summary by CodeRabbit

新機能

  • APIリクエストエラーに、HTTPステータス、URL、元のエラー情報を追加。
  • isMicroCMSRequestError でリクエストエラーを判定可能に。
  • URL内の draftKey は安全のためマスクされます。
  • エラー情報は既存のメッセージ表示やシリアライズ結果に影響しません。

ドキュメント

  • HTTPエラーとネットワークエラーの詳細、エラーハンドリング方法をREADMEに追加。

@coderabbitai

coderabbitai Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 78a83a4a-2cdb-4a73-976c-af9b6d0d53a8

📥 Commits

Reviewing files that changed from the base of the PR and between 0f19af4 and 2790315.

📒 Files selected for processing (1)
  • src/lib/error.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/error.ts

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


Walkthrough

APIリクエスト失敗時のエラーにstatus、url、originalErrorを追加しました。isMicroCMSRequestErrorを公開し、通常クライアントとManagementクライアント、README、テストを更新しました。

Changes

リクエストエラー情報

Layer / File(s) Summary
エラー型と生成・判定処理
src/types.ts, src/lib/error.ts, src/index.ts, tests/lib/error.test.ts
MicroCMSRequestError型、生成関数、型ガードを追加しました。付加プロパティを非列挙にし、URL内のdraftKeyを***に置換します。
クライアントのエラー生成統合
src/createClient.ts, src/createManagementClient.ts, tests/createClient.test.ts
HTTPエラーとネットワークエラーをMicroCMSRequestErrorでラップします。ステータス、URL、元エラー、JSONパースエラーの扱いをテストします。
エラーハンドリング文書
README.md, README_en.md
型ガードの使用方法、エラー種別ごとのプロパティ、draftKeyのマスク、非列挙プロパティを文書化します。

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Fetch
  participant ErrorFactory
  Client->>Fetch: APIリクエスト
  Fetch-->>Client: HTTP応答またはネットワークエラー
  Client->>ErrorFactory: エラー情報を渡す
  ErrorFactory-->>Client: MicroCMSRequestErrorを返す
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは、リクエストエラーにステータスコード、URL、原因を追加して参照可能にするという主要な変更を正確かつ簡潔に示しています。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 7…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 7 files.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@Sinhalite
Sinhalite marked this pull request as ready for review September 2, 2026 07:08
@Sinhalite
Sinhalite requested a review from dc7290 September 2, 2026 07:09
Comment thread src/lib/error.ts
Comment on lines +19 to +38
Object.defineProperties(microCMSRequestError, {
status: {
value: status,
enumerable: false,
configurable: true,
writable: true,
},
url: {
value: maskDraftKey(url),
enumerable: false,
configurable: true,
writable: true,
},
originalError: {
value: originalError,
enumerable: false,
configurable: true,
writable: true,
},
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なんとなくですが、Errorクラスを拡張して新たにErrorクラスを作るのが一般的ですかね?
Object.definePropertiesを選んだ理由などがあれば知りたいです!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dc7290
ありがとうございます!
こちらはAIとのやり取りでも論点になったところでしたね・・!

今回はマイナー/パッチリリースを想定しており、既存のErrorのconstructor、name、通常のconsole.log表示、列挙・シリアライズ結果への影響をできる限り避けることを優先しました。
そのため、従来どおり生成したErrorに非列挙プロパティを追加する方式を選択しています。

メジャーバージョンアップのタイミングであれば、破壊的変更として影響範囲を明示したうえで、Errorを継承した独自classへ移行する方が、良いのかなとは思っています。

今回は後方互換性を優先したこの方式で進めたいと考えていますが、違和感があれば相談させてください!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sinhalite
なるほどですね・・・!

Errorクラスを拡張した上で後方互換性を保つ方法がないか調べてましたが、かなり複雑になるのと完璧には保てなさそうだったので、
マイナーバージョンでのリリースを考えると今回の方法で良さそうです!👍

1点、理想となる実装パターンと次のメジャーバージョンで移行したい旨をコメントに残しておけるとより良さそうですかね?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、もしくは今回メジャーバージョンリリースするという手は無しなんですかね??
今回の実装でリリースした後に、独自classへ移行してもらう方がユーザーに手間をかけてしまうような気もしており、、、

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dc7290
諸々検討ありがとうございます!

1点、理想となる実装パターンと次のメジャーバージョンで移行したい旨をコメントに残しておけるとより良さそうですかね?

マイナーバージョンで進める場合はこちらは残しておくようにします!

あ、もしくは今回メジャーバージョンリリースするという手は無しなんですかね??
今回の実装でリリースした後に、独自classへ移行してもらう方がユーザーに手間をかけてしまうような気もしており、、、

選択肢としてはありそうです!
ただ、今回のエラーハンドリング改善だけを理由にメジャーバージョンを上げるのは、変更内容とのバランスを考えると少し重いように感じています。
将来的な移行コストもそこまで大きくなさそうなので、ほかの破壊的変更と合わせたメジャーアップデートのタイミングで、改めて検討するのがよいかなと考えた部分ではありました!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sinhalite

将来的な移行コストもそこまで大きくなさそうなので、ほかの破壊的変更と合わせたメジャーアップデートのタイミングで、改めて検討するのがよいかなと考えた部分ではありました!

ここは少し気になっていて、「他の破壊的変更と合わせる」だと、まとまった分だけ1回のアップデートが重くなる可能性もあるなと思っています。
また、この先あるかわからない破壊的変更を前提に、公開APIの理想形を先送りする、という立て付けもやや弱い気がしています・・・!

とはいえ、JS SDKはユーザーも多いので気軽にメジャーは上げたくない、という点には同意です!
今回ユーザーが得たい価値(status / url / originalError と type guard)は、現状の方式でも届けられるので、マイナーで進める判断自体は妥当だと思いました。

独自 Error class については、「他の破壊的変更待ち」ではなく、
「Error の identity(constructor / name / instanceof)を変える価値が、単独のメジャーに見合うと判断したタイミング」
で改めて入れる、くらいの基準にしておけると良さそうです。
理想形と移行意図のコメントは残してもらえると助かります!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dc7290
ありがとうございます!

たしかにメジャーアップデートの条件が曖昧に受け取られそうとは思ったため、提案いただいた価値ベースの記述に変更してます!
(コメントだけだと長くなりそうだったので、一部PRをリンクする形としました。)
2790315

@dc7290 dc7290 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

対応ありがとうございます!
LGTM👍

@Sinhalite
Sinhalite merged commit 8832fe5 into microcmsio:main Sep 3, 2026
6 checks passed
@Sinhalite
Sinhalite deleted the codex/improve-request-errors branch September 3, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants