「エラーが出ないまま間違っている」を4件並べたら、2種類に分かれました

前回は、動いているコードに赤線が出た話を書きました。
今回はその逆で、赤線が出ないまま間違っていたほうの話です。

自作アプリ「Hubpin」(Next.js 16 + Supabase)のログイン機能を作っていた2日間で、
この手の間違いが4件そろいました。
並べてみたら、同じ「エラーが出ない」でも2種類に分かれていました。

目次

構文エラーは、いちばん安全でした

設定ファイルに matcher: の行を二重に貼り付けたことがあります。

Expected ',', got ':'

即座に止まりました。

このときは「またやった」と思ったのですが、被害を数えるとゼロです。
動く前に止まっているので、間違ったものが外に出ていません。直せば終わりでした。

危ないのは、構文が正しくて意味が違うもの

同じ設定ファイルで、こちらも踏みました。

export const config = {
  matcher: ['/dashboard/:path*'],
}

構文は完全に正しいので、何も言われません。
ログインの保護も効きます。動作確認も通ります。

症状が出たのは1時間後でした。作業中に突然ログアウトされます。

matcher は「どのパスで処理を動かすか」の設定で、「どのパスを保護するか」ではありません。
保護したいパスだけに絞ると、それ以外のページでセッションの更新が止まります。
このあたりは別で1本書く予定なので、ここでは踏んだ事実だけにしておきます。

厄介だったのは、保護が効いているせいで正しく動いたように見えたことでした。

2種類を並べてみる

気づくまで 気づける理由
構文エラー 即座 動かないから
意味の間違い 1時間後・翌日・本番 動くから気づけない

構文エラーのほうが怖く見えていました。赤いので。
実際にかかったコストは、直すのに使った数分だけです。

意味の間違いのほうは、そのまま完成まで行きます。
自分で書いて、自分で動作確認して、通ってしまう。

同じ日に4件そろっていました

2日間で踏んだものを並べると、こうなりました。

何をした 出たもの いつ気づいたか
matcher: を二重に貼り付け Expected ',', got ':' 即座
await の付け忘れ Cannot read properties of undefined 即座
<form action="{login}"> 何も出ない 送信してみて
matcher を絞りすぎ 何も出ない 1時間後

3件目は、引用符を1組付けただけの間違いです。

<form action="{login}">   // 文字列「{login}」を渡している
<form action={login}>     // 関数 login を渡している

JSX の { は「ここから JavaScript」の合図ですが、" の中では合図として働きません。
文字列として何も不正ではないので、赤線は出ませんでした。

症状も「何も起きない」ではありませんでした。
{login} という名前のURLへ送信されて404になります。
ブラウザは action の中身を送信先として読むので、そのとおりに動いただけでした。

分けたあとで見え方が変わったこと

4件を並べて気づいたのは、軸が1つしかないことでした。
動く前に止まるか、動いてしまうか。

そして、上2件のように即座に止まるものを、自分はずっと「失敗」として数えていました。
実際には止めてもらっています。

意味の間違いのほうは、気づいた時点で1時間分の作業が上に乗っていて、
しかも症状がログアウトという形で出たので、
まず「何が起きたのか」を突き止めるところから始めることになりました。

どちらが高くついたかははっきりしています。

おわりに

「エラーが出た」を失敗、「エラーが出ない」を成功として受け取っていたのですが、
この4件を並べたあとは順序が逆に見えています。

赤くなったものは、その場で終わりました。
静かに通ったものだけが、後ろに時間を持っていきました。

次回は、この「静かに通る」がもっと分かりにくい形で出た話を書きます。
黙る場所が3つ重なると、症状はいちばん遠いところに出ました。

目次