recaptcha
recaptcha copied to clipboard
Uncaught (in promise) Timeout recaptcha__en.js
Google captcha is working well but console show up the error after some time
Would you be able to provide a bit more information about how to reproduce this, please. Preferably a URL and instructions for what to do to see this error in the console.
I can provide a partial stacktrace of this. Comes from production so it's mangled, though. Maybe it'll still point you to the right place...
Uncaught (in promise) timeout
setTimeout (async)
p @ recaptcha__en.js:99
(anonymous) @ recaptcha__en.js:306
CW @ recaptcha__en.js:306
Os @ recaptcha__en.js:482
(anonymous) @ recaptcha__en.js:484
Promise.catch (async)
Os @ recaptcha__en.js:483
ss @ recaptcha__en.js:489
qY.PN @ recaptcha__en.js:486
re @ recaptcha__en.js:490
t.reset @ main.8d559850.js:16
t.componentWillUnmount @ main.8d559850.js:16
Ho @ main.8d559850.js:73
Yo @ main.8d559850.js:73
$a @ main.8d559850.js:73
Xa @ main.8d559850.js:73
Ga @ main.8d559850.js:73
Qa @ main.8d559850.js:73
ts @ main.8d559850.js:73
Ln @ main.8d559850.js:73
In my case, it happens after the unmount of a React component that was presenting a recaptcha. It has been occurring consistently for a few months.
react-google-recaptcha claims this issue live in here. It seems to be related to when the recaptcha is unmounted, at an undetermined time later, a timeout error occurs in the browser.
Maybe there is a step missing in react-google-recaptcha when removing the widget. Here are the steps done to remove the widget properly :
- Removing all nodes from the container use in the grecaptcha.render method
- Use grecaptcha.reset to reset the widget
So the problem is that you get "Uncaught (in promise) timeout" error after some time after removing the widget. If the steps above are correct then the problem is probably due to recaptcha
@TomPradat does the widget itself still need to be in the dom/exist when reset is called?
Also reproducible in Angular 6 when component hosting the recaptcha widget is destroyed after successful recaptcha check.
Yeah, it causing a lot false alarm..Please fix.
@TomPradat does the widget itself still need to be in the dom/exist when reset is called?
I wondered about that so i forked and try to call reset before unmounting from the dom but i still got the issue
I am also reproducing this, in a blade template in composition with Vue.
setTimeout (async) M @ (anonymous) @ G4 @ next @ (anonymous) @ ig @ Xe @ Qa.send @ gV @ (anonymous) @ (anonymous) @
Any update on this? @rowan-m If you require more information on this bug, do let us know.
EDIT: Nevermind. My comment below did not work, even though at first it looked it did.
I encountered this with an Angular app. There was a detail in the examples on the reCAPTCHA v2 docs page, that I just found. In one of the examples, you can see that they are capturing the result of the call to widget = ...render()
and then whenever the form is submitted, they are calling reset()
by passing to it the result of the render()
call. I replicated this with my app and it worked. I no longer get the timeout console errors. It seems that just calling reset()
without passing any parameters isn't actually reset the "default" widget as the docs state.
This is what I did, and so far it seems to be working without throwing the timeout error:
// This code is in TypeScript.
private renderedWidget: any;
// In some function, I call the render() on the global grecaptcha object.
this.rendered = window.grecaptcha.render(...);
/**
* Later, after doing my async request, I reset the captcha like this for both success and failure scenarios.
* You can also call this when your component is unloaded/destroyed.
* If your component isn't unloaded after using the reCAPTCHA response
* until the timeout period, you may receive the timeout
* error, so you should reset the widget as early as possible.
*/
...
window.grecaptcha.reset(this.rendered);
...
Yeah, it takes a while before error appear, maybe 15-30 seconds or so. Maybe some internal timeout or something is triggered? Anyway, only 'fix' I could come up with is to reload the page, which sucks.
I think I have another solution, though, it may be specific to Angular. I made a few observations since my last comment above and think I have a fairly stable solution now.
- The
Uncaught (in promise): Timeout
comes fromzone.js
. This makes it seem that there is an unhandled promise timeout, whichzone.js
is bubbling-up. - Resetting the widget after using the response token is the right thing to do. However, doing so seems to be producing another error
n is null
sporadically along with the promise timeout error.
So I made two changes:
- Run all functions of
grecaptcha
usingNgZone
'srunOutsideAngular()
, which prevents any errors from recaptcha bubbling-up to the main app itself. For example,
// Sample for an Angular app.
...
constructor(private zone: NgZone){}
...
...
this.zone.runOutsideAngular(() => window.recaptcha.render(...));
...
- Call the
reset()
function outside any HTTP client subscriptions. That is, don't callreset()
from within any RxJS subscriptions. (I forget the reason why I had to do this, but it was due to some weird errors)
With the above two changes, I believe I have the widget working in a stable manner in an Angular app. I believe you could apply similar semantics to a React or Vue app as well.
I do have to admit that not having access to the un-minified source for the JS client made things very difficult. I spent way too much time identifying traffic lights, crosswalks, and fire hydrants trying to get confirm that my changes made a difference. On top of that, this repo appears to only talk about the PHP client, and makes no mention of the JS client. I searched for a different repo that would have the JS client, but couldn't find one.
I also have same error on unmounting component in react.js app.
I also encountered this; though from my tests it's happening when the iframe URL fails to load. I can reproduce by blocking network requests to: https://www.google.com/recaptcha/api2/anchor?*
and waiting for the timeout.
I've just hit on a possible approach to handling the error: in the ready
event, make an explicit call to execute
and wrap this in a try/catch. I'm assuming that the library attempts to call execute internally on load and does nothing to handle timeout errors.
It would be nice not to have to hack around this issue - e.g. provide a timeout or error callback...
The issue is still there
Same here with plain JavaScript. Trying to remove the widget as @TomPradat said, getting the timeout after 15-30 Seconds :(
I have get rid of recaptcha in all of my projects. Too much problems, and it seems it will break soon for everybody, since there is new requirements for http headers from new chrome
Hi all, I figured out the issue with Angular today. It seems that because Angular replaces the body of the document with its own content, it actually removes the recaptcha badge from the page. This badge is required for recaptcha to function properly, although it can be set to visibility: hidden;
in CSS (just not display: none;
).
My solution is in my Angular app's main.ts
file, I added this to run after Angular's bootstrap:
platformBrowserDynamic().bootstrapModule( AppModule ).then(() => {
// due to some issues with how recaptcha and angular interact,
// we have to load the recaptcha script after angular bootstraps
let node = document.createElement('script');
node.src = 'https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY';
node.async = true;
node.defer = true;
document.getElementsByTagName('head')[0].appendChild(node);
}
This ensures that the script is loaded after the page has loaded completely and Angular has finished initializing everything.
We have seen this error too. The user reported that they left our SPA (React) open overnight (laptop hibernating) and in the morning they could not log in until they restarted their browser, though we (and they) have been unable to replicate it. Logs show them hitting this error on each login attempt.
We load the script once (<script src='...'>
) for the lifetime of the SPA, and call execute()
for each login attempt.
I notice a couple of react/grecaptcha npm packages inject via Javascript and wondered whether it that might avoid badge issues @computerwizjared mentioned hitting in Angular. However, it looks like react-google-recaptcha suffers anyway (https://github.com/dozoisch/react-google-recaptcha/issues/103) so maybe that wouldn't make any difference.
Perhaps since this happens when we call execute rather than spontaneously after an amount of time, I should open a new issue?
Stacktrace in case it is useful:
Timeout
(anonymous) @ recaptcha__en.js:497
Promise.catch (async)
ST @ recaptcha__en.js:496
CI @ recaptcha__en.js:502
[our code from here]
I also experience the same issue on my react app with invisible recaptcha V2. My flow is:
- Load the library with a callback in the URL:
https://www.google.com/recaptcha/api.js?onload=recaptchaLoadCallback&render=explicit
- In the
recaptchaLoadCallback
, render recaptcha and include a callback in the options: `const widgetId = grecaptcha.render(domId, {... callback: callbackFn ... } - On component load, in a react's useEffect hook, call
window.grecaptcha.execute(widgetId.current)
- When the
callbackFn
is called get the token argument and submit my form with it. After that, performgrecaptcha.reset(widghetId)
What I tried:
- Made sure nothing in my
callbackFn
in step 4 throws errors. - Tried to return a promise and resolve or reject it from the
callbackFn
- Tried to both stop rendering and keep rendering the
<div id={domId} />
where recaptcha is rendered in step 2. Stopping rendering in certain combos of other stuff caused an error be thrown about being unable to read styles of undefined etc. which is expected. - Tried simply removing the DOM element where recaptcha is rendered before / after
grecaptcha.reset(widgetId)
with DOMNode.remove() to avoid the subtleties of react.
None of this helped to resolve the issue for now. Here is the stacktrace if it could be useful:
Uncaught (in promise) Timeout (h)
setTimeout (async)
f @ recaptcha__lt.js:115
(anonymous) @ recaptcha__lt.js:364
Mn @ recaptcha__lt.js:19
next @ recaptcha__lt.js:18
(anonymous) @ recaptcha__lt.js:19
EP @ recaptcha__lt.js:19
cx @ recaptcha__lt.js:18
Ww.send @ recaptcha__lt.js:364
(anonymous) @ recaptcha__lt.js:520
Promise.then (async)
V.bZ @ recaptcha__lt.js:520
a.H @ recaptcha__lt.js:365
(anonymous) @ recaptcha__lt.js:365
Mn @ recaptcha__lt.js:19
next @ recaptcha__lt.js:18
O @ recaptcha__lt.js:19
Promise.then (async)
Y @ recaptcha__lt.js:19
(anonymous) @ recaptcha__lt.js:19
EP @ recaptcha__lt.js:19
cx @ recaptcha__lt.js:18
Ww @ recaptcha__lt.js:364
(anonymous) @ recaptcha__lt.js:363
$6 @ recaptcha__lt.js:100
uz @ recaptcha__lt.js:99
KP.O @ recaptcha__lt.js:99
Show 24 more blackboxed frames
I think I solved it:
When you destroy Recaptcha component in your preferred JS framework, make sure you set
window.grecaptcha = null
window.recaptcha = null
After this you shouldn't see timeout error anymore.
window.grecaptcha = null
window.recaptcha = null
No, this doesn't solve the error.
Additional thing to do is
document.querySelectorAll(‘iframe[src*=recaptcha]’).forEach(a => a.remove())
Same "problem" (working well, but error in console) with Divi WordPress Theme and recaptcha V3.
I also encountered the same error in my react app while integrating the firebase's phone authentication.
Finally I tried the code below, but unfortunately same error continues to exist... ( I also removed the container element of the recaptcha from the virtual dom of react )
window.recaptchaVerifier.reset();
window.recaptchaVerifier.clear();
window.recaptchaVerifier = null;
I solved my error by calling grecaptcha.execute
only when submiting a form .
I have an AngularJS app and i included the script inside index.html
<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
after doing so i used ng-click on a button on another html page and on the controller i wrote the function below
function _registerNewUser() {
grecaptcha.ready(function () {
grecaptcha.execute('YOUR_SITE_KEY', { action: 'register' }).then(function (token) {
$http.post(serviceBase + 'api/Google', { GoogleToken: token }).then(function (response) {
............
}, function (response) {
.........
});
});
});
}
The Post request inside the execute of recaptcha is to verify the user's token. After implementing the Recaptcha with this way i was able to solve this issue. To my understanding the problem was on the onCallBack function mentioned in the URL of the index .
Regarding the callback function you can see on the Recaptcha page that google's suggestion is not to use the callback function but just in case you want to , you can implement it as it was implemented in the V2 Recaptcha.
Quotting Google :
Tips
- grecaptcha.ready() runs your function when the reCAPTCHA library loads. To avoid race conditions with the api.js, include the api.js before your scripts that call grecaptcha, or continue to use the onload callback that's defined with the v2 API.
- Try hooking the execute call to interesting or sensitive actions like Register, Password Reset, Purchase, or Play.
Can we please get a fix for this? We've been working on a fix before this post and tbh, after coming back two years later and it still not fixed is quite saddening :( https://github.com/DethAriel/ng-recaptcha/issues/123
The repo owner of the link even describes and also says it resides in an unsolved promise in recaptcha__en.js
, any update?
I also had this console warning when debugging without server-side verification (call to Google API to verify if reCAPTCHA client response is valid). My implementation includes dynamically created element for every captcha necessary and is in plain JS so everyone can refer to. In my case app
url is address of Node.js application for server-side verification.
Solved my issue with code below:
https://gist.github.com/ANTOSzbk/75ed7003e914162550f61399122a3bd4
Some update?