「10箇所直す」だと思っていたら、作るのは1箇所だった

転職用のポートフォリオとして、個人でWebアプリ「Hubpin」を作っています。
制作の経緯は「Hubpin 開発記録」に時系列でまとめています。

自分のコードをレビューする工程で、直したい書き方が10箇所見つかりました。

TypeScript でいう非nullアサーション、変数のうしろに付ける ! です。
値が無いかもしれない、と型が言っているのに、無いはずがない、と書き手が言い切る書き方です。

10箇所か、と身構えました。

目次

数えたら、10箇所とも同じ種類でした

腰を据えて見てみたら、全部が環境変数の読み出しでした。

process.env.NEXT_PUBLIC_SUPABASE_URL!

しかも、同じ2つの環境変数を、4つのファイルがそれぞれ読んでいました。
5ファイルに2箇所ずつで、そのうち4ファイルはまったく同じ2行です。

10箇所というのは症状の数で、原因の数ではありませんでした。

作ったのは1箇所でした

環境変数を読む入口を1つ作って、他のファイルはそこから読む形にしました。

function required(name: string, value: string | undefined): string {
  if (!value) {
    throw new Error(`環境変数 ${name} が設定されていません`)
  }
  return value
}

export const env = {
  supabaseUrl: required('NEXT_PUBLIC_SUPABASE_URL', process.env.NEXT_PUBLIC_SUPABASE_URL),
  // 以下、必要な値をここに並べる
}

これで10箇所の ! が消えました。
ファイルを1つ足しただけです。

おまけがありました

! を消すのが目的でしたが、途中で別の問題も片付いていました。

! は型に対して言い切っているだけで、実際に値が無いときには何もしてくれません。
値が空のまま進んで、まったく別の場所で落ちます。

実際、以前この形で困ったことがあります。
環境変数が無いことが原因なのに、エラーはURLの解析に失敗した、という内容で出ました。
原因から遠い場所で落ちるので、たどるのに時間がかかります。

入口を1つにすると、読み込みの時点で値の有無を確かめられます。
無ければ、どの環境変数が足りないかを名前で言って止まります。

この形は、あとの工程で効きました。
本番環境だけがエラーになったとき、変数名を挙げて止まってくれたので、原因が5分で分かりました。

件数で見積もると重く見える

10箇所と聞いたときは、半日仕事だと思っていました。

実際には、同じ原因が10回顔を出していただけでした。

見積もる前に、その件数が何種類あるかを数えるほうが先だったと思います。
種類が1つなら、解決策も1つです。

目次