When a browser catches an error from a JavaScript file hosted on a different origin, it replaces the error details with a generic "Script error." message. This is a browser security feature defined by the same-origin policy. Because the error message, source URL, and line number are all stripped, these errors are difficult to diagnose in ARMS Browser Monitoring.
This topic explains why "Script error." occurs and describes two fixes: enabling CORS (recommended) and wrapping calls in try...catch. A final section covers how to filter out script errors in the ARMS SDK when they are not actionable.
Why browsers hide cross-origin error details
Browsers enforce the same-origin policy on error reporting. If a page at http://test.com loads a script from http://another-domain.com/app.js, the browser blocks detailed error information from reaching the page's window.onerror handler. This prevents third-party scripts from leaking sensitive data through error messages.
Example: A page loads a cross-origin script that calls an undefined function.
<!doctype html>
<html>
<head>
<title>Test page in http://test.com</title>
</head>
<body>
<script src="http://another-domain.com/app.js"></script>
<script>
window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
foo(); // Calls foo() defined in app.js
</script>
</body>
</html>// another-domain.com/app.js
function foo() {
bar(); // ReferenceError: bar is not a function
}Instead of the actual ReferenceError, the window.onerror handler receives:
"Script error.", "", 0, 0, undefinedInternally, the browser sanitizes the error before passing it to the page:
bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage, int& lineNumber, String& sourceURL)
{
KURL targetURL = completeURL(sourceURL);
if (securityOrigin()->canRequest(targetURL))
return false;
errorMessage = "Script error.";
sourceURL = String();
lineNumber = 0;
return true;
}The most common cause is hosting JavaScript on a CDN. Because the CDN domain differs from your page domain, all errors from those scripts appear as "Script error.".
Solution 1: Enable CORS (recommended)
To get full error details from cross-origin scripts, configure both the script tag in your HTML and the response headers on the server that hosts the script.
Step 1: Add the crossorigin attribute to the script tag
<script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>The crossorigin="anonymous" attribute tells the browser to fetch the script without sending credentials (cookies or client certificates) to the third-party server.
Step 2: Add the CORS response header on the server
The server hosting the script must return the Access-Control-Allow-Origin header. To allow all origins:
Access-Control-Allow-Origin: *To restrict access to your domain:
Access-Control-Allow-Origin: http://test.comMost CDN providers already include the Access-Control-Allow-Origin header by default. To verify, run:
curl --head https://retcode.alicdn.com/retcode/bl.js | grep -i "access-control-allow-origin"Expected output:
access-control-allow-origin: *Verify the fix
After you complete both steps, reload the page. The window.onerror handler now receives the full error:
"ReferenceError: bar is not defined", "http://another-domain.com/app.js", 2, 1, [Object Error]Solution 2: Wrap calls in try...catch
When you cannot modify the server's CORS headers -- for example, with a third-party script you do not control -- wrap the cross-origin function calls in a try...catch block.
<!doctype html>
<html>
<head>
<title>Test page in http://test.com</title>
</head>
<body>
<script src="http://another-domain.com/app.js"></script>
<script>
window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
try {
foo(); // Calls foo() defined in app.js
} catch (e) {
console.log(e);
throw e;
}
</script>
</body>
</html>The catch block captures the full error, including the stack trace:
ReferenceError: bar is not defined
at foo (http://another-domain.com/app.js:2:3)
at http://test.com/:15:3The window.onerror handler still receives "Script error.". To report the captured error to ARMS, call the SDK's error reporting method inside the catch block:
__bl.error(error, pos);For the full API reference, see SDK methods.
Solution 1 (CORS) is the preferred approach. Use try...catch only when you cannot configure cross-origin headers.
Filter out script errors in ARMS
If script errors come from third-party scripts that do not affect your application, filter them from your ARMS data by using the SDK's ignore parameter.
The ignore parameter accepts an object with three properties:
ignore: {
ignoreUrls: [],
ignoreApis: [],
ignoreErrors: []
}To filter out script errors, use the ignoreErrors property. It accepts a string, a regular expression, a function, or an array combining these types.
Example: Filter out all "Script error." messages with a regular expression:
__bl.setConfig({
ignore: {
ignoreErrors: /^Script error\.?$/
}
});