エラーを読んでみる

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部

このレッスンで分かること

  • エラーは「種類」「説明」「ファイル名と行番号」の 3 点セットで読みます
  • よく出るのは ReferenceError SyntaxError TypeError の 3 つです
  • 最小例は function errorType(message) { return message.split(":")[0]; }

エラーを読んでみる とは

コンソールに出る赤いメッセージの読み方を覚えます。エラーの種類と行番号から、直す場所を自分で見つけられるようになります。

エラーは敵ではない

コードを書くと必ずエラーが出ます。ベテランでも 1 日に何十回も出します。違いは、出た瞬間に読むか、見ないふりをして当てずっぽうで直すかだけです。エラーメッセージは「どこが」「どう」おかしいかを教えてくれる、いちばん親切なヒントです。

コンソールに出るエラーは、次のような形をしています。

Uncaught ReferenceError: userName is not defined at startupMessage (script.js:5:10) at script.js:12:1

分解すると 3 つの情報が入っています。

部分内容この例では
エラーの種類どんな種類の失敗かReferenceError
説明何が起きたかuserName is not defined
発生場所ファイル名と行と桁script.js:5:10

読む順番はこの表の下から上です。まず script.js の 5 行目を開き、そのあたりで userName という名前を探します。桁の 10 は行の中の何文字目かを表します。at から始まる行が複数あるのは、関数がどこから呼ばれたかをさかのぼって示しているためで、これをスタックトレースと呼びます。いちばん上が、実際に落ちた場所です。

Uncaught は「誰も受け止めなかった」という意味です。第 10 章より先で学ぶ try を使うとエラーを受け止められますが、入門のうちは無視して構いません。読むのは種類と説明と行番号の 3 点です。

よく出る 3 つの種類

エラーの種類は名前を見ただけで原因の見当が付きます。まずは 3 つ覚えます。

種類意味代表的な原因
ReferenceErrorその名前が見つからない変数名のつづり間違い、定義前の使用
SyntaxError文法として読めないカッコやクォートの閉じ忘れ
TypeError型が合わないので操作できないundefined の中身を取ろうとした

ReferenceError

存在しない名前を使ったときに出ます。多くはただのタイプミスです。

function startupMessage() { return "こんにちは、" + userName; }
Uncaught ReferenceError: userName is not defined at startupMessage (script.js:2:29)

is not defined は「そんな名前は定義されていない」という意味です。user_name と書いたつもりが userName になっていた、というような大文字小文字の違いでも起きます。JavaScript は大文字と小文字を別物として扱います。

SyntaxError

文法として成立していないときに出ます。プログラムを実行する前の読み取り段階で止まるため、そのファイルの処理は 1 行も動きません。

function startupMessage(name) { return "こんにちは、" + name;
Uncaught SyntaxError: Unexpected end of input at script.js:3:1

Unexpected end of input は「まだ閉じていないのにファイルが終わった」という意味です。閉じカッコの不足が代表例です。この種類のエラーは、示された行そのものではなく、その少し前に原因があることが多いので、上へさかのぼって探します。

SyntaxError が出たとき、行番号はファイルの末尾を指しがちです。「最後まで読んだけど閉じられていなかった」ことに気づくのが末尾だからです。行番号を鵜呑みにせず、対応するカッコを上へたどってください。

TypeError

名前は存在するけれど、その値に対してできない操作をしたときに出ます。

function firstWorkTitle(works) { return works[0].title; } firstWorkTitle();
Uncaught TypeError: Cannot read properties of undefined (reading '0') at firstWorkTitle (script.js:2:15)

Cannot read properties of undefined は「undefined の中身は取り出せない」という意味です。引数を渡し忘れた、関数が return を書き忘れていて undefined が返ってきた、といった原因が典型です。カッコの中の reading '0' が、何を取ろうとしたのかを教えてくれます。

わざと壊して確かめる

エラーは待っていても来ません。自分から出しにいくのが、いちばん早い練習です。script.js に次の 3 つを順番に書いて、コンソールに何が出るか見てください。

console.log(userName); console.log("こんにちは、" + name; console.log(undefined.title);

1 つ目は ReferenceError、2 つ目は SyntaxError、3 つ目は TypeError です。順番に試すつもりでも、2 つ目を書いた時点でファイル全体が SyntaxError で止まるため、1 つ目のメッセージは出ません。文法エラーは実行前に判定される、という違いをここで体感できます。

種類いつ判定されるか他の行への影響
SyntaxError実行する前ファイル全体が動かない
ReferenceError実行中その行で止まる。前の行までは動く
TypeError実行中その行で止まる。前の行までは動く

この表の違いは重要です。console.log を仕込んだのに何も出ないときは、たいてい SyntaxError でファイルごと止まっています。まずコンソールの一番上まで戻って、赤い行を探してください。

課題では種類を取り出す

今回の課題は、エラーメッセージの文字列を受け取って、先頭の種類だけを返す関数です。メッセージは ReferenceError: userName is not defined のように、種類のあとに半角コロンが来る形で統一されています。つまり、コロンより前を切り出せば種類が取れます。

function errorType(message) { return message.split(":")[0]; } console.log(errorType("TypeError: Cannot read properties of undefined")); // => TypeError

split は文字列を指定した記号で区切って配列にするメソッドです。配列は第 5 章で詳しく扱いますが、ここでは [0] と書くと「区切った 1 つ目」が取れる、とだけ覚えておけば足ります。

実務では、エラーの文字列をそのまま検索窓に貼るのがいちばん速い解決法です。ただし自分のファイル名や変数名が入った部分は消してから検索してください。Cannot read properties of undefined のような共通部分だけを残すと、同じ症状の記事が見つかります。

よくある間違い

  • エラーを読まずに書き直す — 赤い文字を見た瞬間に閉じてしまい、勘で直そうとするパターンです。まず種類と行番号を声に出して読みます
// 誤り。works が undefined でも気づかないまま書き換え続ける return works[0].title;
  • 行番号だけを見て前後を見ない — とくに SyntaxError は、原因が示された行より前にあります。カッコとクォートの対応を上へたどります
// 3 行目でエラーと出るが、原因は 2 行目の閉じカッコ不足 function startupMessage(name) { return "こんにちは、" + name;
  • 大文字と小文字を同じだと思うuserNameusername は別の名前です。ReferenceError の半分はこれが原因です
// 誤り return "こんにちは、" + username; // 正しい return "こんにちは、" + userName;

要件

  1. 関数名は errorType、引数は message の 1 つ (文字列)
  2. 戻り値は先頭の種類だけの文字列 (ReferenceError SyntaxError TypeError など)
  3. 半角コロンより前の部分を切り出すこと
  4. コロンが含まれない文字列を渡された場合は、受け取った文字列をそのまま返すこと

入出力例

errorType("ReferenceError: userName is not defined")"ReferenceError" errorType("SyntaxError: Unexpected end of input")"SyntaxError" errorType("TypeError: Cannot read properties of undefined (reading 'title')")"TypeError" errorType("ReferenceError")"ReferenceError" errorType("")""

ヒント

main.js
main.js
学習モード

メモ

エラーを読んでみる

⌘S で保存