Fail fast when loading google maps asynchronously - javascript

I have an web app where some pages use the google maps API.
I'm using the async load with callback like explained in the documentation : https://developers.google.com/maps/documentation/javascript/tutorial?csw=1#asynch
It works great when the network connection is ok.
However, if for whatever reason, the browser fails to download the google maps script, it will hang for about 10 second before an unrecoverable connection an error. That network error stops the script execution and I cannot continue with my app process.
I want to recover from that error to continue the process of my webapp just with a info message telling the user that Google Maps isn't availaible for the moment.
I tried the following but it obviously doens't work because of cross domain xmlhttprequest access :
$.get("https://maps.googleapis.com/maps/api/js?key=.......",function(){
var googlemapsscript = document.createElement('script');
googlemapsscript.type = 'text/javascript';
googlemapsscript.src = 'https://maps.googleapis.com/maps/api/js?key=........&sensor=false&callback=successLoadGoogleMaps';
document.body.appendChild(googlemapsscript);
}).fail(function(){
errorLoadGoogleMaps();
});
When it has trouble accessing Google Maps API, the jquery $.get fails, thus running immediately errorLoadGoogleMaps(). However when it can access the API it throws the cross domain error.
I'm looking for the following behavior :
- Try to download Google Maps API
- Fail fast if it isn't availaible
- If available, continue with the success callback
Currently as a bad workaround I'm using a callback written in the script element :
googlemapsscript.onerror="errorLoadGoogleMaps()"
However it doesn't fail fast at all, the browser try to download the script for about 10 seconds before throwing the error and executing the callback.
How to fail immediately when trying to download an unavailable script (in particular Google Maps API here) ?

You might want to uses jQuery.getScript(), which should takes care a lot of errors handing, and browser supporting for you.

Related

Google Auth OAuth 2.0 SvelteKit wierd behavior

I am using Google Auth OAuth 2.0 One Tap Sign and Sveltekit,
and I got some really weird behavior,
I followed this doc https://developers.google.com/identity/gsi/web/guides/overview with javascript
onMount(async () => {
const handleCredentialResponse = async (response) => {
console.log('Encoded JWT ID token: ' + response.credential);
};
google.accounts.id.initialize({
client_id: clientId,
callback: handleCredentialResponse,
});
google.accounts.id.renderButton(
document.getElementById('buttonDiv'),
{ theme: 'outline', size: 'large' } // customization attributes
);
google.accounts.id.prompt();
});
the code from the doc.
Sometimes it works everything goes well,
Sometimes I got
Uncaught (in promise) ReferenceError: google is not defined
And some mobile / mobile browsers I get
[GSI_LOGGER]: The given origin is not allowed for the given client ID.
but works on laptop
Hope someone can understand and help.
Do we have any way to check logs for investigation?
I got your code to successfully run without modification: https://google-signin-kit.vercel.app/ (This app is in "dev" mode so signin may only succeed with my Google account. If you clone my repo and set your Google client id, signin will work for you.)
I would check how my code is different from your code outside onMount(). For example, how did you include the Google javascript? I describe one major change below.
You also need to check your Google app settings. [GSI_LOGGER]: The given origin is not allowed... is fixed by adding the HTTPS app domain to your Google app "Authorized JavaScript origins." Non-HTTPS domains are not allowed. For example, these domains would not work:
https://google-signin-kit-leftium.vercel.app/ (Not added as Authorized JavaScript origin)
http://google-signin-kit.vercel.app/ (Not HTTPS, if Vercel did not automatically redirect to HTTPS)
Of course, raw IP addresses will not work, either.
localhost is a special exception, but not easy (impossible?) to access from mobile.
ReferenceError: google is not defined (sometimes) happens because onMount() runs before the Google script is loaded.
To get a consistent reproduction, USB debug/inspect Android Chrome and set "disable caching" and throttling to "Slow 3G." (I could not reproduce on desktop Chrome).
Fixed by removing defer async when including Google's script: <script src="https://accounts.google.com/gsi/client"></script>
It should also be possible to call a function after the script is loaded, but I got inconsistent results in SvelteKit. For some reason Kit doesn't always call the load function. Possibly a bug?
Ideally, the Google script should be imported, but I couldn't find a version of the Google script that was built for importing. You may be able to construct a library that you can import? Importing would compile the Google script code into your app, tree-shaking the unused portions. Thus saving a network request and bandwidth.
Another workaround is to have your onMount function check for the google variable. If google is still undefined, call your function again after a certain timeout.

Retrieving console errors to html

My question is different from the other posts similar to this.
AutoCAD offers developers a means of displaying a URL page inside the application. I created an intranet site for my company with the hopes that users can explore via desktop browser or their AutoCAD application.
The problem is that the browser AutoCAD uses is Chrome version 33 (currently its at 84) - there is no way to update or change the browser either.
I have no way to "inspect" or debug the site inside AutoCAD - and I've come to find out there are many difference in v84 and v33. I'm trying to diagnose errors right now but again, I have no way of accessing the console logs inside the AutoCAD Browser.
Is there a way for me to "alert" any errors that the console is trying to give me? (ie: the page can't find a script reference, there is an unexpected '.', etc...)
NOTE - my site runs great on the most updated Chrome browser (v84 on desktop browser), but some little things are not working right in v33 (in AutoCAD Browser).
If you control the website you can attach a listener on the window to listen for any unhandled exceptions. Add this before all other scripts to make sure everything is captured.
window.on('error', (e) => {
// if error is intresting, do work.
alert(e.message);
});
The handler accepts an ErrorEvent object.
NOTE - This will not capture errors that are triggered in scripts across domain. For example if you are loading google maps, and an error is triggered within that script, you will typically get a 'Script error.' and no other info. This has to do with cross origin policies. You can read more here.
If you need to specifically to capture data sent to console.error you can simply proxy the function. This may not capture anything except for code that explicitly calls console.error and is not recommended.
const error = console.error;
console.error = (...args) => {
// alert(...);
error.apply(console, args);
}

Js - Capturing a 400 error event that appears in console

I'm creating a chrome extension for Facebook that runs a script in the page.
Facebook in its normal operation sometimes shows the following message in the Chrome console (with red):
kZLAjcLHBWC.js:26 GET https://www.facebook.com/ufi/reaction/profile/browser/fetch/?limit=50&shown…=o&__req=9w&__be=-1&__pc=PHASED%3ADEFAULT&__rev=2661965&__srp_t=1478186873 400 ()
I want to create any js function that will determine when this event is happening (the 400 GET error).
It's going to be challenging to catch from a content script; since it's not a JS error that bubbles up, it has to be caught in the page's own code, and there are barriers to that. They can be overcome, but then you're operating in the possibly hostile environment of the page's code.
An alternative is to use webRequest API, specifically chrome.webRequest.onErrorOccurred event. This will allow you to detect errors on specific requests.
However, this can't be done from a content script. You'd need a background script that messages the content script when the event happens.

Swift Headless WKWebView; running XMLHttpRequest

How can I run an XMLHttpRequest from within a WKWebView that I have created in Swift?
Currently, I use the WKWebView to access a page on a server I own. This page contains my Javascript. However, when I attempt to make an XMLHttpRequest by using WKWebView.evaluateJavaScript (i.e. call a javascript function that makes an XMLHttpRequest) the Javascript code executes successfully but the Safari debugger shows "Failed to load resource".
However, if I 'manually' make an XMLHttpRequest by using the console in the Safari debugger and then call my request function from my app, it works fine - but only once!
I'm at a bit of a loss as to why this is...
As mentioned in the comments, a better solution than bundling the Javascript with my swift library is to host the scripts on a page that is accessed via the WKWebView. Previous information maintained below;
Some background: I have been tasked with producing a Swift library that wraps our current Javascript API. I had hoped to use a WKWebView to simply load and execute our existing javascript code, however any XMLHttpRequests that I run simply return error (fire the onerror callback) instantly. The error object returned to onerror is {"position":0,"totalSize":0}
This thread seems to suggest that my WKWebView needs a 'parent' in order to execute javascript correctly. I have attempted to reproduce their code in Swift, but to no effect (see below)
let webConf = WKWebViewConfiguration()
WKWebView webView = WKWebView(frame: CGRectZero, configuration: webConf)
UIApplication.sharedApplication().keyWindow?.addSubview(webView)
In order to get to this point, I have had to set 'App Transport Security Settings -> Allow Arbitrary Loads' to 'YES' in my info.plist file, in order to enable non-https requests.

Finding a strange Javascript function 'window.ueLogError' in a PhantomJS error message

I'm working on a project that involves retrieving multiple websites with PhantomJS and when I try to load Amazon.com, PhantomJS crashes while trying to evaluate this function with the error:
TypeError: 'undefined' is not a function (evaluating 'window.ueLogError')
The weird thing is that I can't seem to find any documentation or explanation of any kind for window.ueLogError. A google search gives a handful of websites with scripts that contain it, but it doesn't seem to be a part of any documentation I can find. Does anyone know anything about ueLogError?
The window object is the global sink in the browser. Every variable that you define globally (e.g. jQuery's $) is a property in window. ueLogError is not some kind of standardized JavaScript function. It is most likely some function for an advertisement script.
Not all resources that a page requests as part of the page load are actually successfully loaded. Some requests fail due to SSL problems. Some requests fail, because the user agent string is not supported. Some requests fail because of unknown reasons.
You can register to the onConsoleMessage, onError, onResourceError, onResourceTimeout events (Example) to see whether there are errors. Usually you will find that some JavaScript file wasn't loaded which would have contained ueLogError which another script depends on.

Categories

Resources