リクエストエラーからステータスコード・URL・原因を参照できるようにする - #109
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. WalkthroughAPIリクエスト失敗時のエラーに Changesリクエストエラー情報
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を返す
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation 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)
Comment |
| 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, | ||
| }, | ||
| }); |
There was a problem hiding this comment.
なんとなくですが、Errorクラスを拡張して新たにErrorクラスを作るのが一般的ですかね?
Object.definePropertiesを選んだ理由などがあれば知りたいです!
There was a problem hiding this comment.
@dc7290
ありがとうございます!
こちらはAIとのやり取りでも論点になったところでしたね・・!
今回はマイナー/パッチリリースを想定しており、既存のErrorのconstructor、name、通常のconsole.log表示、列挙・シリアライズ結果への影響をできる限り避けることを優先しました。
そのため、従来どおり生成したErrorに非列挙プロパティを追加する方式を選択しています。
メジャーバージョンアップのタイミングであれば、破壊的変更として影響範囲を明示したうえで、Errorを継承した独自classへ移行する方が、良いのかなとは思っています。
今回は後方互換性を優先したこの方式で進めたいと考えていますが、違和感があれば相談させてください!
There was a problem hiding this comment.
@Sinhalite
なるほどですね・・・!
Errorクラスを拡張した上で後方互換性を保つ方法がないか調べてましたが、かなり複雑になるのと完璧には保てなさそうだったので、
マイナーバージョンでのリリースを考えると今回の方法で良さそうです!👍
1点、理想となる実装パターンと次のメジャーバージョンで移行したい旨をコメントに残しておけるとより良さそうですかね?
There was a problem hiding this comment.
あ、もしくは今回メジャーバージョンリリースするという手は無しなんですかね??
今回の実装でリリースした後に、独自classへ移行してもらう方がユーザーに手間をかけてしまうような気もしており、、、
There was a problem hiding this comment.
@dc7290
諸々検討ありがとうございます!
1点、理想となる実装パターンと次のメジャーバージョンで移行したい旨をコメントに残しておけるとより良さそうですかね?
マイナーバージョンで進める場合はこちらは残しておくようにします!
あ、もしくは今回メジャーバージョンリリースするという手は無しなんですかね??
今回の実装でリリースした後に、独自classへ移行してもらう方がユーザーに手間をかけてしまうような気もしており、、、
選択肢としてはありそうです!
ただ、今回のエラーハンドリング改善だけを理由にメジャーバージョンを上げるのは、変更内容とのバランスを考えると少し重いように感じています。
将来的な移行コストもそこまで大きくなさそうなので、ほかの破壊的変更と合わせたメジャーアップデートのタイミングで、改めて検討するのがよいかなと考えた部分ではありました!
There was a problem hiding this comment.
将来的な移行コストもそこまで大きくなさそうなので、ほかの破壊的変更と合わせたメジャーアップデートのタイミングで、改めて検討するのがよいかなと考えた部分ではありました!
ここは少し気になっていて、「他の破壊的変更と合わせる」だと、まとまった分だけ1回のアップデートが重くなる可能性もあるなと思っています。
また、この先あるかわからない破壊的変更を前提に、公開APIの理想形を先送りする、という立て付けもやや弱い気がしています・・・!
とはいえ、JS SDKはユーザーも多いので気軽にメジャーは上げたくない、という点には同意です!
今回ユーザーが得たい価値(status / url / originalError と type guard)は、現状の方式でも届けられるので、マイナーで進める判断自体は妥当だと思いました。
独自 Error class については、「他の破壊的変更待ち」ではなく、
「Error の identity(constructor / name / instanceof)を変える価値が、単独のメジャーに見合うと判断したタイミング」
で改めて入れる、くらいの基準にしておけると良さそうです。
理想形と移行意図のコメントは残してもらえると助かります!
概要
microCMS APIへのリクエストが失敗した際に、原因調査に必要な情報をエラーオブジェクトから参照できるようにしました。
以下の要望への対応を目的としています。
fetchなどが持つ、ネットワークエラーのcauseやエラーコードを確認したい関連Issue:
Network Error. Details: TypeError: fetch failed発生時の詳細情報が知りたい #82変更内容
microCMS APIへのHTTP・ネットワークエラーに、以下のプロパティを追加しました。
statusundefinedurloriginalErrorundefinedfetchが投げた元の値あわせて、TypeScriptから安全にエラーを判定・参照できるよう、以下を公開しました。
MicroCMSRequestError型isMicroCMSRequestErrortype guardContent APIとManagement APIのmicroCMS APIリクエストに適用しています。
後方互換性について
独自のエラーclassは導入せず、従来どおり生成した通常の
Errorへ追加情報を付与しています。追加プロパティは非列挙としているため、以下の既存挙動を維持します。
error instanceof Errorerror.constructor === Errorerror.nameerror.messageerror.toString()console.log(error)の通常表示Object.keys(error){ ...error }JSON.stringify(error)既存のエラーメッセージ形式、リトライ条件・回数・間隔・ログ内容も変更していません。
また、HTTP成功後のJSONパースエラーなど、本変更の対象外となるエラーは従来どおりそのまま返します。
将来的な独自 Error class の検討
将来、Error の identity(
constructor/name/instanceof)を変更する価値が、メジャーバージョンアップに見合うと判断した場合は、以下のような独自 Error class への移行を検討できます。セキュリティへの配慮
リクエストURLに
draftKeyが含まれる場合は、その値だけを***へマスクします。他のクエリパラメータとURLは保持します。以下の情報はエラーへ追加しません。
ResponseオブジェクトoriginalErrorの形式はNode.js、ブラウザ、Edge Runtimeなどの実行環境によって異なるため、SDKとして具体的な形式は保証しません。確認
npm test -- --runInBandnpm run typechecknpm run lintnpm run formatnpm run buildstatus、マスク済みurl、既存のconsole.log(error)表示を確認Summary by CodeRabbit
新機能
isMicroCMSRequestErrorでリクエストエラーを判定可能に。draftKeyは安全のためマスクされます。ドキュメント