top of page

exist で重複判定したら、未作成のコレクションまで「既に登録されています」になった

独自の会員登録フォームで、同じメールアドレスが使われていたときに「既に登録されています」と出したい。エラーの文面で判定するのが手軽である。

if (/already|exist/i.test(raw)) {
  return 'このメールアドレスは既に登録されています。';
}

この正規表現は広すぎる。Wix の英語エラーには does not exist という文面がある。コレクションやフィールドが作られていないときに出るものである。exist にそのまま一致する。

別の障害が、利用者には行き止まりに見える

コレクションが未作成というのは、開発中には普通に起こる。実際に、参照しているコレクションを作り忘れたまま WDE0025 が出続けていた期間がある。

その状態で広い判定を通すと、画面には「既に登録されています」と出る。利用者から見れば、自分のメールアドレスが使われていることになる。別のアドレスで試す。同じエラーが出る。何をしても同じである。

開発者から見ても厄介で、報告されるのは「重複エラーが出る」という症状になる。会員の重複を疑って調べても、そんな会員はいない。原因はデータベース側にあるのに、症状はまったく別の場所を指している。

判定は、意図した条件の最小の証拠に合わせる

直し方は、一致させる範囲を狭めることに尽きる。

const isDuplicate =
  /already\s*(exists|registered|in\s+use|taken)|ALREADY_EXISTS/i.test(raw);

already の直後に来る語まで見る。エラーコードがあるならそれも並べる。does not exist はどの枝にも一致しない。

あわせて、未知のエラーは未知のまま扱う。魅力的だが根拠の無い分類へ流し込まない。

if (isDuplicate) {
  return 'このメールアドレスは既に登録されています。';
}
return '登録処理でエラーが発生しました。時間をおいてお試しください。';

2つ目の文言は情報量が少ない。それでいい。原因を名指しできないときに名指しすると、利用者は間違った行動を取る。技術的な詳細は別の欄へ出して、そこで開発者が読めるようにしておく。

そもそも文面で分岐しなくてよいか

文面での判定は、プラットフォーム側の文言が変われば黙って壊れる。エラーコードが得られるなら、そちらを優先する。WDE0025 のようなコードは、少なくとも英語の文章より変わりにくい。

それでも文面を見る場面は残る。外部 API を経由している、ライブラリが包み直している、といった理由でコードが手元まで来ないことがあるからである。そのときは、次の2つを守るだけでも事故はかなり減る。

  • 一致させる範囲を、意図した条件を示す最小の形に絞る

  • どれにも当てはまらないエラーのための枝を必ず残す

Velo

実装

備忘録

コラム

その他

カテゴリー

bottom of page