Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

クライアント側エラー

最終更新 Markdown で表示Agent セットアップ

Turnstile で問題が起きると、error-callback が呼び出されることがあります。

問題の範囲は、ネットワーク接続、ブラウザー互換性、設定ミス、チャレンジの失敗までさまざまです。

エラー発生時に適切なエラー処理を実装すると、訪問者にわかりやすいフィードバックを出せます。一時的な問題からもアプリケーションを回復できます。

具体的なエラー条件への対処は、エラーコード のトラブルシューティングを参照してください。

エラー処理

明示的レンダリングの error-callback オプションと、暗黙的レンダリングの data-error-callback 属性は、発生したエラーを処理する JavaScript コールバックを提供します。

このコールバックで、訪問者へのエラー表示を完全に制御できます。アプリケーションに合わせた独自の回復戦略も実装できます。

turnstile.render('#my-widget', {
  sitekey: 'your-sitekey',
  'error-callback': function(errorCode) {
    console.error('Turnstile error occurred:', errorCode);
    handleTurnstileError(errorCode);
    return true; // Indicates we handled the error
  }
});
HTMLhtml
<div class="cf-turnstile" 
     data-sitekey="your-sitekey" 
     data-error-callback="onTurnstileError"></div>

エラーコールバックの指定は任意ですが、本番アプリケーションでは推奨します。エラーコールバックを設定しないと、Turnstile はエラー時に JavaScript 例外を投げます。ページの動作が乱れ、ユーザー体験が悪化することがあります。エラーコールバックを用意すれば、これらの例外を捕捉して処理できます。

エラーコールバックが falsy でない値を返すと、Turnstile はエラーを処理済みとみなし、追加のエラーログは出しません。falsy な結果(undefined を含む)を返すと、Turnstile はエラーコードを含む警告を JavaScript コンソールに出力します。開発中のデバッグに役立ちます。

エラーコールバックの第 1 引数はエラーコードです。先頭 3 桁がエラーファミリー(設定、ネットワーク、チャレンジ失敗など)を示し、残りの桁がそのファミリー内の具体的なエラーを示します。

function handleTurnstileError(errorCode) {
  const errorFamily = Math.floor(errorCode / 1000);
  
  switch(errorFamily) {
    case 100:
      showMessage('Please refresh the page and try again.');
      break;
    case 110:
      showMessage('Configuration error. Please contact support.');
      break;
    case 300:
    case 600:
      showMessage('Security check failed. Please try refreshing or using a different browser.');
      break;
    default:
      showMessage('An unexpected error occurred. Please try again.');
  }
}

再試行

既定では、Turnstile は問題発生時に自動で再試行します。一時的なネットワーク障害や短いサービス停止を、ユーザー操作なしで処理できます。

この自動再試行は、接続が途切れやすい モバイル訪問者 や、安定性にばらつきがあるネットワーク上の訪問者に有効です。

再試行後の失敗が続くと、同じ根本原因に対してエラーコールバックが複数回呼ばれることがあります。重複したエラーメッセージや、同じ回復処理の繰り返しを避けるよう、エラー処理コードでこの可能性を考慮してください。

let retryCount = 0;

turnstile.render('#my-widget', {
  sitekey: 'your-sitekey',
  'error-callback': function(errorCode) {
    retryCount++;
    
    if (retryCount <= 2) {
      console.log(`Turnstile retry attempt ${retryCount}`);
      return false; // Let Turnstile handle the retry
    } else {
      showPersistentErrorMessage(errorCode);
      return true; // We'll handle it from here
    }
  }
});

再試行の動作は、既定の auto ではなく never に設定して調整できます。この場合 Turnstile は自動再試行しません。いつ、どのように回復を試みるかは、こちらで制御します。訪問者の検証で問題やエラーが起きても、ウィジェットは再試行せず、手動で対処するまで失敗状態のままです。

turnstile.render('#my-widget', {
  sitekey: 'your-sitekey',
  retry: 'never',
  'error-callback': function(errorCode) {
    // You control all retry logic
    setTimeout(() => {
      turnstile.reset('#my-widget');
    }, 3000);
  }
});

対応する error-callback 内で turnstile.reset() を呼び、手動で再試行できます。指数バックオフ、再試行前のユーザー確認、エラー内容に応じた再試行戦略など、独自の再試行ロジックを実装する場合に有効です。

再試行の間隔は retry-interval オプションで設定できます。訪問者の一般的なネットワーク状況に合わせて最適化してください。低速または不安定な接続では長めの間隔が適します。安定した環境では短い間隔でも問題ありません。

turnstile.render('#my-widget', {
  sitekey: 'your-sitekey',
  retry: 'auto',
  'retry-interval': 8000, // Wait 8 seconds between retries
  'error-callback': handleError
});

インタラクティビティ

訪問者が対話型チャレンジに妥当な時間内で応じないと、タイムアウトコールバックが呼ばれます。この仕組みで、チャレンジが無限に待機状態のままになるのを防ぎ、操作が必要なときに訪問者へフィードバックできます。

たとえば、完了まで数分かかるフォーム内に Turnstile ウィジェットがある場合、対話型チャレンジを長時間放置すると古くなります。訪問者がフォーム入力に集中して Turnstile チャレンジを見落とすと、期限切れまたは無効なトークンのまま送信しようとすることがあります。

このような場合、ウィジェットの timeout-callback が起動します。必要に応じてウィジェットをリセットし、適切な案内を出せます。Turnstile ウィジェットの強調表示、通知の表示、チャレンジの自動更新など、わかりやすいタイムアウト処理を実装できます。

turnstile.render('#my-widget', {
  sitekey: 'your-sitekey',
  callback: function(token) {
    console.log('Challenge completed successfully');
  },
  'timeout-callback': function() {
    console.log('Challenge timed out - user action required');
    document.getElementById('challenge-notice').textContent = 
      'Please complete the security check above to continue.';
    
    // Optionally highlight the widget
    document.getElementById('my-widget').style.border = '2px solid orange';
  },
  'expired-callback': function() {
    console.log('Token expired - challenge needs refresh');
    document.getElementById('challenge-notice').textContent = 
      'Security check expired. Please try again.';
  }
});

役に立ちましたか?