Script errors are common errors. However, no complete error message or error stack is available for errors of this type. Therefore, these errors are difficult to troubleshoot. This topic analyzes the causes, provides solutions, and shows you how to ignore this type of error in Application Real-Time Monitoring Service (ARMS).
Causes of script errors
Script errors are also called cross-origin errors. When a website requests and executes a script hosted under a third-party domain name, a script error may occur. The most common scenario is to use a content delivery network (CDN) to host JavaScript (JS) resources.
For better understanding, assume that the following HTML page is deployed in the http://test.com domain name:
<!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(); // Invokes the foo method defined in the app.js file.
</script>
</body>
</html>
Assume that the foo
method invokes an undefined bar
method:
// another-domain.com/app.js
function foo() {
bar(); // ReferenceError: bar is not a function
}
After the page is loaded, the following error is captured:
"Script error.", "", 0, 0, undefined
In fact, this is not a JS error. For security reasons, browsers deliberately hide specific errors thrown by JS files of other origins. This way, sensitive information can be effectively prevented from being inadvertently captured by uncontrolled third-party scripts. Therefore, only scripts from the same origin can capture specific error messages, whereas scripts from other origins can detect errors but cannot capture specific error messages. For more information, see Webkit source code.
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 following sections describe how to resolve script errors.
Solution 1: Enable cross-origin resource sharing
To capture JS errors across origins, perform the following steps:
-
Add the
crossorigin="anonymous"
attribute.<script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>
This step tells the browser to anonymously obtain third-party scripts. This means that the browser does not send potential user identity information, such as cookies and HTTP certificates, to the server when the browser requests scripts.
-
Add the cross-origin HTTP response header. For example, you can run the following command:
Access-Control-Allow-Origin: *
Alternatively, you can run the following command:
Access-Control-Allow-Origin: http://test.com
Note By default, most mainstream CDNs have theAccess-Control-Allow-Origin
attribute. The following example is from Alibaba Cloud CDN:$ curl --head https://retcode.alicdn.com/retcode/bl.js | grep -i "access-control-allow-origin" => access-control-allow-origin: *
After the preceding two steps are performed, you can capture cross-origin errors by
using the window.onerror
handler. In the preceding example, after the page is loaded again, the following
error is captured:
=> "ReferenceError: bar is not defined", "http://another-domain.com/app.js", 2, 1, [Object Error]
Solution 2: Add the try catch
command (Optional)
When a cross-origin attribute is difficult to be added to the HTTP request or response
header, add the try catch
command.
Add the try catch
command to the preceding HTML page. The following code provides an example:
<!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(); // Invokes the foo method defined in the app.js file.
} catch (e) {
console.log(e);
throw e;
}
</script>
</body>
</html>
Load the page again. The following information is returned:
=> ReferenceError: bar is not defined
at foo (http://another-domain.com/app.js:2:3)
at http://test.com/:15:3
=> "Script error.", "", 0, 0, undefined
The try catch
command generates complete error information in the console log, but the window.onerror
handler generates only script errors. You can manually report captured exceptions
in the try catch command. For more information, see API reference.
__bl.error(error, pos);
try catch
command can be used to capture some exceptions, we recommend that you use Solution
1.
How can I ignore script errors in ARMS?
Script errors usually come from scripts under third-party domain names. If script errors does not affect the running of your application, you can ignore them by setting the ignore parameter of the ARMS frontend monitoring SDK.
The ignore
parameter allows you to ignore the reporting of specified JS errors. The value of
this parameter is an object that contains three properties: ignoreUrls, ignoreApis, and ignoreErrors. The following code shows the default value of this parameter:
ignore: {
ignoreUrls: [],
ignoreApis: [],
ignoreErrors: []
},
Use the ignoreErrors property to ignore script errors. The ignoreErrors property is used to ignore JS errors that comply with a specified rule. The value of this property can be a string (the String type), a regular expression (the RegExp type), a method (the Function type), or an array that includes the preceding three types. The following code provides an example on how to ignore script errors:
__bl.setConfig({
ignore: {
ignoreErrors: /^Script error\.?$/
}
});