Error Handling
Handle errors and edge cases in Crovly widget integration.
Error Codes
The onError callback receives a code and a human-readable message.
| Code | Description |
|---|---|
TIMEOUT | The PoW challenge took too long to solve (>30s) |
NETWORK_ERROR | Failed to reach the Crovly API |
CHALLENGE_FAILED | The server rejected the challenge request |
VERIFICATION_FAILED | The PoW solution was invalid or the score was too low |
UNKNOWN | An unexpected error occurred |
onError Callback
HTML Widget
<script src="https://get.crovly.com/widget.js"
data-site-key="YOUR_KEY"></script>
<div id="crovly-captcha"></div>
<script>
document.addEventListener('crovly:error', (e) => {
console.error('Crovly error:', e.detail.code, e.detail.message);
});
</script>JavaScript API
Crovly.render('#container', {
siteKey: 'YOUR_KEY',
onError: (code, message) => {
switch (code) {
case 'TIMEOUT':
showMessage('Verification timed out. Please try again.');
break;
case 'NETWORK_ERROR':
showMessage('Network error. Check your connection.');
break;
case 'VERIFICATION_FAILED':
showMessage('Verification failed. Please try again.');
break;
default:
showMessage('Something went wrong. Please try again.');
}
},
});React
<CrovlyCaptcha
siteKey="YOUR_KEY"
onError={(code, message) => {
setError(`Verification error: ${message}`);
}}
/>Auto-Retry Behavior
The widget automatically retries failed challenges up to 3 times with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 second |
| 2nd retry | 2 seconds |
| 3rd retry | 4 seconds |
After 3 failed retries, the onError callback fires and the widget shows an error state with a "Retry" button.
Auto-retry applies to NETWORK_ERROR and CHALLENGE_FAILED errors. TIMEOUT and VERIFICATION_FAILED errors are not retried automatically since they indicate a problem that is unlikely to resolve on its own.
Manual Retry
Reset the widget to trigger a fresh verification attempt:
// JavaScript API
Crovly.reset('#container');// React
const { reset } = useCrovly();
reset();You can also provide a retry button in your UI:
<div id="crovly-captcha"></div>
<button id="retry-btn" style="display:none" onclick="Crovly.reset('#crovly-captcha')">
Try Again
</button>
<script>
Crovly.render('#crovly-captcha', {
siteKey: 'YOUR_KEY',
onError: () => {
document.getElementById('retry-btn').style.display = 'block';
},
onVerify: () => {
document.getElementById('retry-btn').style.display = 'none';
},
});
</script>Common Error Scenarios
TIMEOUT
Cause: The user's device is too slow to solve the PoW challenge within the time limit, or the difficulty is set too high.
Solution: Use Auto difficulty mode (the default) which adapts to the client. If you are using a fixed difficulty, consider lowering it.
NETWORK_ERROR
Cause: The browser cannot reach api.crovly.com. This can happen due to ad blockers, firewall rules, or network outages.
Solution: Ensure api.crovly.com is not blocked by your Content Security Policy. See the Troubleshooting guide for CSP setup.
CHALLENGE_FAILED
Cause: The challenge nonce expired (60s TTL) or was already used.
Solution: This usually resolves on auto-retry. If it happens consistently, check that your server clock is synchronized.
VERIFICATION_FAILED
Cause: The PoW solution was incorrect, the fingerprint signals indicated a bot, or the IP changed between challenge and verification.
Solution: This is expected behavior for bots and automated tools. For legitimate users on VPNs that rotate IPs, this can be a false positive — consider lowering your score threshold in the dashboard.