この記事について
- 本の要約・感想
 - エラーの読み方について
 - わからないときの情報収集について
 
なぜエラー文を読まないのか
- 英語で書かれているから
 - 長くて読みづらい
 - 読んでもすぐに原因がわからないから
 
エラー文
よく見るケース
X is not defined    ・・・ Xが定義されていません。
X is not a function ・・・ Xは関数ではありません。
X is not iterable   ・・・ Xは繰り返し可能ではありません。
Function statements require a function name ・・・ 関数文は関数名が必要です。
主語が省略されているケース
Cannot read properties of null  ・・・ nullのプロパティを読み取ることができません。
Cannot use 'in' operator ・・・ in 演算子を使うことはできません。
このときの主語はなにか。The programと言い換えることができる。
簡潔な表現が使われるケース
Invalid array length  ・・・ 不正な配列の長さ
Unexpected token '['  ・・・ 予期しないトークン'['
missing ) after argment list ・・・ 引数リストの後ろに)が見当たらない
| フレーズ | 意味 | 
|---|---|
| valid / invalid | 有効な / 不正な | 
| expected / unexpected | 予期した / 予期しない | 
| defined / undefined | 定義された / 未定義の | 
| declared / undeclared | 宣言された / 未宣言の | 
| reference | 参照 | 
| require | 必要とする、必須 | 
| deprecated | 非推奨 | 
| expired | 期限切れ | 
| apply | 適用する | 
| deny | 拒否する | 
| permission | 許可 | 
| range | 範囲 | 
| missing | 見当たらない | 
| function /argument | 関数 / 引数 | 
| variable / constant | 変数 / 定数 | 
| object / property / method | オブジェクト / プロパティ / メソッド | 
| expression / statement | 式 / 文 | 
| operator / operand | 演算子 / 被演算子 | 
| token | トークン | 
| initializer | 初期化子 | 
| mutable / immutable | 変更可能な / 変更不可能な | 
| iteration /iterable | 繰り返し / 繰り返し可能な | 
| assignment | 代入 | 
ライブラリなどのエラー
ライブラリとかサードパーティ内のエラーだと、1行目を見ても、サードパーティ内のソースコードが表示されているため、ほとんどの場合、原因箇所を見るけるのが困難です。
DBのライブラリのように丁寧にエラーコードを返却してくれるようなものならいいですが、実際はそんなことはなかったりします。
このあたりは、アプリケーション側だけでなくそもそもDBの前提知識であったり、ライブラリのドキュメントやGihubのissueを読む力も必要になる。
エラーの種類
エラーにはいくつかの種類がある。以下は代表的なエラーの種類になる。
| Error | 概要 | 内容 | 
|---|---|---|
| SyntaxError | 構文エラー | コードの文法が間違っている場合。カッコやクォート、メソッドの定義など。 | 
| ReferenceError | 参照エラー | 存在しない変数や関数を参照しようとしている。スコープ外の変数を参照したりなど。 | 
| TypeError | 型エラー | 値を不適切な方法で扱った場合。変数を関数のようにmember()っと宣言したりなど。 | 
| RangeError | 範囲エラー | 許容されない範囲の値を扱った場合。配列の長さを定義する言語などで、配列の長さ以上のindexを参照したりなど。 | 
エラー文の読み方
エラー文の構成について
[エラーの種類]: [エラーメッセージ]
    [スタックトレース]
    ...
    ...
    ...
    ...
    ...
大体が上記のような構成。スタックトレースがCasueで階層になって長くなるパターンが多かったり、Web系だと、DOMの情報が表示されてたりで多くなったり。
大体は上記の3点、エラーの種類、メッセージ、スタックトレース(1行目)を見れば良い。
ライブラリやサードパーティを使っているとスタックトレースは見れないことがあるが、エラーの種類やメッセージは同様に表示される。ものによっては、エラーコードなどがきちんと定義されており出力してくれる。
スタックトレースを読む
スタックトレースは、at メソッド(ファイル 行目:文字目)という形で、エラーが発生するまでの流れを記したもの。
※ 言語によって若干異なる。
メソッド名、ファイル名、行目、文字目を表示してくれる。
メソッドが実行された順に積まれていくため、最後(最初の行)のスタックトレースが最後に実行されたものを示している。
どうしてもわからない場合
Googleを使ったテクニック
"(ダブルクオート)を使うことで、完全一致の検索をすることができる。
GitHubを使ったテクニック
- 正規表現による完全一致検索
 
Github code searchという機能がある。普通にスペース区切りで検索すると、1単語ずつ、コード内にあれば表示されるが、正規表現を使うことで、Googleと同じように完全一致したものだけを絞り込むことができる。
- パス検索
 
path:パス名 っで検索することで、該当するパスに絞って検索する事ができる。
tailwind.config.jsで絞りたい場合は以下のようになる。
path:tailwind.config.js
コミュニティに質問する
StackOverflowやteratail、Githubのissueなど、有識者が集まるようなコミュニティに質問する。情報量や返答率の観点から、英語圏のコミュニティのほうが良い。
質問するときは最低限のポイントを抑えること。
- 具体的で明確なタイトルを付ける
 - 問題の詳細を網羅的に記述する
- 操作方法
 - エラーの内容
 - 期待している動き
 
 
一時情報を読む
- 公式ドキュメント
 - GitHubなどのIssue
 - ライブラリのソースコード
 
エラーが見やすくなるコードの書き方
再代入はしない
// よくない例
let data = getData();
    // 処理
data = data.sort();
    // 処理
data = data.filter();
// 改善案
const data = getData();
    // 処理
const sortedData = data.sort();
    // 処理
const filteredData = data.filter();
- デバッグがしやすくなる
 - データの変化がわかりやすくなる
 
スコープは可能な限り狭める
// よくない例
function () {
    const data = getData();
    if( ... ) {
        // dataを使う
    } else {
        // dataを使わない
    }
}
// 改善案
function () {
    if( ... ) {
        // dataを使う
        const data = getData();
    } else {
        // dataを使わない
    }
}
- スコープが広がることで、データの流れを読むときに、読むべき範囲が多くなってしまう
 - パフォーマンスが悪化する
 - 変更がやりづらくなる
 
単一責任の原則
クラスや関数などのコードを持つ責務を1つにするべき っというルールのこと。
純粋関数を利用する
純粋関数とは2つの条件を満たしたものを言う。
- 引数が同じであれば、戻り値は同じとなる
 - 副作用がない
 
// 純粋関数ではないもの
let x = 0;
function add(a) {
    return x + a
}
add(3) ・・・ 3
x = 100;
add(3) ・・・ 103
// 副作用 ・・・ 関数外の状態(変数など)を変更すること
let numbers = [ 1, 2, 3, 4];
function fn(x) {
    numbers.push(5);
}
- 純粋関数は、関数内で完結しているため読みやすく、デバッグもしやすい
 - すべてを純粋関数で書くことは難しい
 
まとめ
- 簡単なエラーの種類や見方、デバッガの使い方について
 - エラーの見方だけでなく、良いコードの書き方、簡単な概念を説明してくれる
 - 英語大事
 
 


コメント