What's the heck is "Script error"?
Ben vinegar/May,
If you've done onerror a work with the JavaScript event before, you ' ve probably come across the following:
"Script error."
"Script Error" is what browsers send to the onerror callback when an error originates from a JavaScript file served from a different Origin (different domain, port, or protocol). It's painful because even though there ' s an error occurring and you don't know what's the error is, nor from which code it ' s originating. And that's the whole purpose of window.onerror –getting insight into uncaught errors in your application.
The Cause:cross-origin scripts
To better understand what's going on, consider the following example HTML document, hypothetically served from Http://exam Ple.com/test:
<!doctype html><title>example.com/test</title><body><scriptSrc="Http://another-domain.com/app.js"></script><script>Window.OnError=function (messageurl linecolumnerror) {console. Log (messageurllinecolumnerror ); } foo (); //call function declared in App.js </script></body>< Span class= "NT" ></HTML>
Here ' s the contents of Http://another-domain.com/app.js. It declares a single function, foo and whose invocation would always throw a referenceerror.
// another-domain.com/app.jsfunction foo() { bar(); // ReferenceError: bar is not a function}
When this document was loaded in the browser and JavaScript are executed, the following is output to the console (logged via The window.onerror callback):
"Script error.", "", 0, 0, undefined
This isn ' t a JavaScript bug–browsers intentionally hide errors originating from the script files from the different origins for Security reasons. It's to avoid a script unintentionally leaking potentially sensitive information to an onerror callback that it doesn ' t co Ntrol. For this reason, browsers only give window.onerror insight into errors originating from the same domain. All we know are that's an error occurred–nothing else!
I ' m not a bad person, really!
Despite browsers ' good intentions, there is some really good reasons why do you want insight into errors thrown from scripts Served from different origins:
- Your application JavaScript files is served from a different hostname, e.g. Static.sentry.io/app.js.
- You is using libraries served from a community CDN, like Cdnjs or Google's Hosted libraries.
- You're working with a commercial 3rd-party JavaScript library, that's only served from external servers.
But don ' t worry–getting insight into a JavaScript error served by these files just needs a few simple tweaks.
The Fix:cors attributes and headers
In order to get visibility-a JavaScript exception thrown from scripts originating from different origins, you must do The things.
1) Add a crossorigin= "anonymous" script attribute
<script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>
This tells the browser, the the the target file should be fetched "anonymously". This means, no potentially user-identifying information like cookies or HTTP credentials would be transmitted by the BR Owser to the server when requesting this file.
2) Add a cross Origin HTTP header
Access-Control-Allow-Origin: *
CORS is short for "Cross Origin Resource sharing", and it's a set of APIs (mostly HTTP headers) that dictate how files Oug HT to is downloaded and served across origins.
By setting Access-Control-Allow-Origin: * , the server was indicating to browsers, which any origin can fetch this file. Alternatively, you can restrict it for only a known origin you control, e.g.
Access-Control-Allow-Origin: https://www.example.com
Note:most community CDNs properly set an Access-control-allow-origin header.
$ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | grep -i "access-control-allow-origin"Access-Control-Allow-Origin: *
Once both of these steps has been made, any errors triggered by this script would report to window.onerror just like any regular SA Me-domain script. So instead of "Script error", the onerror example from the beginning would yield:
"ReferenceError: bar is not defined", "http://another-domain.com/app.js", 2, 1, [Object Error]
boom! You ' re done– "Script error" would plague you and your team no more.
An alternative Solution:try/catch
Sometimes, we ' re not always on a position to being able to adjust the HTTP headers of scripts our web application are Consumin G. In those situations, there are an alternative approach:using try/catch.
Consider the original example again, this time with Try/catch:
<!--note:crossorigin= "anonymous" intentionally absent--<scriptSrc="Http://another-domain.com/app.js"></script><script>Window.OnError=function(Message,Url,Line,Column,Error){Console.Log(messageurlline columnerror} try {foo (); //call function declared in App.js catch (e {console. Log (ethrow e//intentionally re-throw (caught by Window.onerror) }</script
For posterity, Some-domain.com/app.js once again looks like this:
// another-domain.com/app.jsfunction foo() { bar(); // ReferenceError: bar is not a function}
Running The example HTML would output the following 2 entries to the console:
=> ReferenceError: bar is not defined at foo (http://another-domain.com/b.js:2:3) at http://example.com/test/:15:3=> "Script error.", "", 0, 0, undefined
The first console Statement–from try/catch–managed to get a Error object complete with type, message, and Stack trace , including file names and line numbers. The second console statement from window.onerror , once again, can only output "Script error."
Now, does the mean you need to try/catch all of your code? Probably not–if You can easily change your HTML and specify CORS headers on your CDNs, it's preferable to doing so and STI CK to window.onerror .
But, if you don't control those resources, using Try/catch to wrap 3rd-party code is a surefire (albeit tedious) how to ge T insight into errors thrown by Cross-origin scripts.
Note:by default, Raven.js–sentry ' s JavaScript sdk–carefully instruments built-in methods to try to automatically wrap Your code in Try/catch blocks. It does attempt to capture error messages and stacks traces from all your scripts, regardless of which origin they ' Re served from. It ' s still recommended to set CORS attributes and headers if possible.
If This blog post helped your out, and you're ' d like to learn more on window.onerror , you should also check out our other blog post: Capture and report JavaScript errors with Window.onerror.
"Go" window.onerror cross-domain issues