よくあるJSONパースエラーと修正方法
予期しないトークン、未終端の文字列、末尾カンマ、不正な値など、最も一般的なJSONパースエラーを診断し、明確な解決策で修正する方法を解説します。
詳細な説明
JSONパースエラーは、JSONパーサーがJSON文法に準拠しないテキストを検出した際に発生します。これらのエラーはパースを完全に停止させ、部分的な結果はありません。最も一般的なエラーパターンとその解決策を理解することは、JSONデータを扱うすべての開発者に不可欠です。
「Unexpected token」エラー:
最も一般的なJSONパースエラーです。パーサーが予期しない位置に文字を見つけたことを意味します。一般的な原因は以下の通りです:
- 末尾カンマ:
{"a": 1,}— パーサーはカンマの後にキーを期待するが}を検出 - シングルクォート:
{'a': 1}— パーサーは"を期待するが'を検出 - クォートなしのキー:
{a: 1}— パーサーは"を期待するがaを検出 - コメント:
{"a": 1 // note}— パーサーは//を認識しない - 先頭のBOM: ファイル先頭の見えないバイトオーダーマーク(U+FEFF)
「Unterminated string」エラー:
文字列が " で開かれたが正しく閉じられない場合に発生します。一般的な原因は、文字列内のエスケープされていないクォート("She said "hello"" は "She said \"hello\"" とすべき)や、文字列内のリテラル改行(代わりに \n を使用)です。
「Unexpected end of input」エラー:
パーサーがまだコンテンツを期待している途中でテキストの終わりに到達しました。これは通常、閉じ角括弧 ]、波括弧 }、またはクォート " の欠落を意味します。入力が完全に空の場合にも発生します。
数値フォーマットエラー:
JSONは数値のフォーマットに厳格です。先頭のゼロ(007)、先頭のプラス記号(+5)、裸の小数点(.5)、16進数(0xFF)、8進数(0o77)、NaN、Infinity はすべて無効です。.5 の代わりに 0.5 を使用し、特殊な数値の概念は文字列またはnullとして表現してください。
エンコーディングの問題:
JSONはUTF-8(推奨)、UTF-16、またはUTF-32でエンコードする必要があります。Latin-1やWindows-1252などの他のエンコーディングで保存されたファイルには、無効なUTF-8バイトシーケンスが含まれる可能性があり、特殊文字でパースエラーが発生します。JSONファイルは常にBOMなしのUTF-8で保存してください。
開発者がよくやるミス:
開発者はしばしばJSONテキストを目視でデバッグしようとしますが、大きなドキュメントでは困難です。代わりに、行番号と列番号を提供するJSONバリデーターを使用してください。もうひとつのミスは、パースエラーをキャッチしても元のエラー詳細を含まない汎用的な「invalid JSON」メッセージをログに記録することで、次のデバッグ担当者にとって解決が不可能になります。また、エラー位置を誤解することもあります。報告される位置はパーサーが諦めた場所であり、必ずしも実際のミスがある場所ではありません。実際の問題は数行前にあることが多いです。
ベストプラクティス:
JSON.parse() は常にtry/catchブロックで囲み、具体的なエラーメッセージをユーザーやログに提供してください。リアルタイムのJSONバリデーション機能を持つエディタを使用し、入力時にエラーを検出しましょう。プログラムでJSONを生成する際は、文字列連結ではなく組み込みのシリアライズ関数を常に使用してください。
ユースケース
サードパーティサービスが文字列値内のエスケープされていない制御文字を含む不正なJSONを送信するため、断続的に失敗するWebhook連携をデバッグする。