INTEGRITY Dokumentace

Chyby na straně klienta

V některých situacích Turnstile narazí na problém a zavolá error-callback.

Tyto problémy sahají od potíží se síťovým připojením a s kompatibilitou prohlížeče až po chyby v konfiguraci a selhání výzvy.

Správné ošetření chyb zajistí, že návštěvník dostane srozumitelnou zpětnou vazbu a že se vaše aplikace z dočasných potíží zotaví.

Viz Kódy chyb s postupy pro řešení konkrétních chybových stavů.

Zpracování chyb

Prvek error-callback pro explicitní vykreslování widgetů a data-error-callback atribut pro implicitní vykreslování poskytuje JavaScriptový callback, který obslouží případné chyby.

Tento mechanismus callbacků vám dává plnou kontrolu nad tím, jak se chyby návštěvníkům zobrazí, a umožňuje zavést vlastní postupy obnovy podle potřeb vaší aplikace.

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
  }
});
HTML
<div class="cf-turnstile" 
     data-sitekey="your-sitekey" 
     data-error-callback="onTurnstileError"></div>

Uvedení chybového callbacku je volitelné, u produkčních aplikací ho ale doporučujeme. Pokud žádný chybový callback nenastavíte, vyvolá Turnstile při chybě výjimku JavaScriptu, což může narušit funkčnost vaší stránky a zhoršit zážitek uživatele. S chybovým callbackem tyto výjimky zachytíte a zpracujete.

Pokud error callback vrátí hodnotu, která není falsy, Turnstile předpokládá, že callback chybu ošetřil, a sám ji už nezaloguje. Pokud error callback vrátí falsy hodnotu (včetně undefined), zapíše Turnstile do JavaScriptové konzole varování s kódem chyby, které se hodí při ladění během vývoje.

Error callback dostane jako první parametr kód chyby. Ten má pevnou strukturu: první tři číslice určují rodinu chyby (například problémy s konfigurací, potíže se sítí nebo selhání výzvy) a zbývající číslice upřesňují konkrétní chybu v rámci této rodiny.

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.');
  }
}

Opakování

Ve výchozím nastavení Turnstile po výskytu problému pokus automaticky zopakuje. Přechodné potíže se sítí nebo krátké výpadky služby se tak vyřeší bez zásahu uživatele.

Tento mechanismus automatického opakování se hodí pro návštěvníci z mobilních zařízení s kolísavým připojením nebo návštěvníky v sítích, kde občas vázne stabilita.

Pokud kvůli opakovaným pokusům nastanou další chyby, může se error callback pro jednu a tutéž příčinu vyvolat několikrát. Počítejte s tím v kódu, který chyby ošetřuje, ať se návštěvníkovi nezobrazují duplicitní hlášky a ať se stejná náprava neprovádí opakovaně.

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
    }
  }
});

Chování při opakovaných pokusech upravíte tak, že hodnotu retry nastavíte na never místo výchozího auto. Turnstile pak nebude pokus opakovat automaticky a vy máte kontrolu nad tím, kdy a jak k obnově dojde. Pokud při ověřování návštěvníka nastane jakýkoli problém nebo chyba, widget pokus nezopakuje a zůstane v příslušném chybovém stavu, dokud nezasáhnete ručně.

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

Můžete zavolat turnstile.reset() v odpovídajícím error-callback k ručnímu spuštění dalšího pokusu. Hodí se, když chcete logiku opakování řešit po svém, například exponenciálním odstupem, potvrzením od návštěvníka před dalším pokusem nebo různými strategiemi podle konkrétní chyby.

Interval mezi opakovanými pokusy lze u Turnstile nastavit pomocí retry-interval v konfiguraci, takže načasování opakovaných pokusů přizpůsobíte typickým síťovým podmínkám svých návštěvníků. Delší interval se hodí pro návštěvníky s pomalejším nebo méně spolehlivým připojením, kratší intervaly fungují dobře tam, kde je připojení obvykle stabilní.

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

Interaktivita

Pokud návštěvník na interaktivní výzvu v přiměřené době nezareaguje, zavolá se timeout callback. Výzva tak nezůstane donekonečna ve stavu čekání a návštěvník se dozví, že se od něj něco očekává.

Představte si třeba formulář, jehož vyplnění zabere několik minut a je v něm vložený widget Turnstile. Pokud návštěvník interaktivní výzvu delší dobu nevyřeší, výzva zastará. Návštěvníci se často soustředí na vyplňování polí a výzvu Turnstile přehlédnou, takže se formulář pokusí odeslat s prošlým nebo neplatným tokenem.

V takových případech timeout-callback widgetu, který se tak může podle potřeby resetovat a zobrazit návštěvníkovi pokyny. Díky tomuto callbacku vyřešíte vypršení platnosti vstřícně k návštěvníkovi, například zvýrazněním widgetu Turnstile, zobrazením upozornění nebo automatickým obnovením výzvy.

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.';
  }
});