What are Script Errors and How Can We Address Them?

Imagine that a customer reports an error on one of your websites. When you check the logs or tracking tool, it just says script error and nothing else. Does it sound familiar? Such errors are difficult to debug because they do not contain additional information about what and where they went wrong. 

Feel free to use these links to navigate the article:

Background: The onerror Callback

Before we set down to understand script errors, it would be wise to take a moment to understand how to handle errors in web browsers. onerror is a unique browser event that fires when JavaScript captures an uncaught error. There are different ways to catch errors in your application. Most of the time, developers use try-catch blocks to handle errors in their applications.

Sometimes an unexpected error may occur in your application. Since you did not know of this error beforehand, you would not have defined a try-catch block for it. But JavaScript provides an onerror handler that captures all the uncaught errors on the client-side. Its definition looks like this:

window.onerror = function (msg, url, lineNo, columnNo, error) {
// ... handle error ...return false;
}

The error object here provides the necessary information that helps to debug the issue. Even though the onerror handler provides detailed information about the uncaught error, there are situations where it cannot provide enough information and will contain just a “Script Error” message.

What are Script Errors?

Script Errors are errors that the browser sends to the onerror callback when they originate from a third-party script. It usually happens when the third-party scripts are from a different origin(different domain, port, or protocol). However, the main purpose of onerror callback in the browser is to collect insights into uncaught errors in the application. So if an error in the window.onerror is hidden or poorly described like Script Errors, finding and fixing the issue will be challenging.

Suppose you are using a third-party script in your application and an onerror event callback to capture errors in your website. You will notice a "script error" message like this:

It is called “script error” because it originates from a JavaScript file or a script served from a different origin, domain, or port. It is difficult to understand and fix because even though there is an error, you do not know what it is and where it originates, which makes fixing the issue difficult.

What Causes Script Errors?

Cross-origin or third-party scripts used in your application throwing an error is the main reason behind script errors. But what are cross-origin scripts? If an application uses a script hosted in a different domain, port, or protocol, it's called a cross-origin script. We use scripts from third-party applications in much more cases than you can imagine. It can be for any purpose, ranging from a chat system to analytical tools.

Let's take a simple example to understand the reasons for script errors. Here, we have a simple web page that uses a third-party script.

<!doctype html>
<html>
<head>
  <title>example.com/test</title>
</head>
<body>
  <script src="https://vigilant-mayer-281134.netlify.app/index.js"></script>
  <script>
    window.onerror = function (message, url, line, column, error) {
      console.log(message, url, line, column, error);
    }
    xyz(); // call function declared in index.js
  </script>
</body>
</html>


The third-party script looks like this:

function xyz() {
    abc(); // ReferenceError: abc is not a function
}

When you load the document in the browser, it captures the error and sends it to window.onerror as

"Script error.", "", 0, 0, undefined

The script error message is not a problem with JavaScript or your application’s code. The web browser intentionally hides the error originating from third-party scripts for security reasons. It is mainly to avoid leaking sensitive information from third-party scripts to an onerror callback. Another reason is that it does not have control over the callback function. For this purpose, browsers only allow information to window.onerror from the same origin.

Web browsers hide the error information mainly to avoid cross-site request forgery (CSRF). CSRF is an attack that forces an end user to execute unwanted actions on web applications. Then, it precisely captures the user information based on that unwanted action. Browsers hide cookies and HTTP authentication data to prevent such CSRF attacks.

However, script errors can also occur if the script is stored on the same domain but uses a different port or protocol.

How to Fix Script Errors

So, how do you fix these script errors in your application? Or, to be more precise, how do you get enough information from third-party scripts to debug the issue so that you may analyze and fix it? There are a few steps you can use to fix the script error.

Add the cross-origin Attribute on the Script

While loading a third-party script, add the crossorigin script attribute in the tag. You can do it like this:

<script crossorigin="anonymous" src="https://vigilant-mayer-281134.netlify.app/index.js"></script>

It indicates to the browser that it should fetch the third-party script anonymously. It means that browsers should not send sensitive information such as cookies or HTTP credentials to the third-party server when requesting this file.

Once you add the crossorigin attribute, browsers will request this third-party script without sensitive data such as cookies or HTTP authentication. It is important to fetch third-party static files anonymously because static files are one of the prime sources of CSRF attacks.

Set the Access-Control-Allow-Origin Header

Access-Control-Allow-Origin header indicates whether the given origin can access the resource or not. Most of the time, Content Delivery Network(CDN) hosts third-party scripts, solving Cross-Origin Resource Sharing(CORS) errors. But if you are running your server or the third party which is not using CDN for serving static files, it needs to return the following HTTP header for static files:

Access-Control-Allow-Origin: *

The wildcard works fine most of the time. But, if this is a private host for a known set of domains, you can configure the domain list instead of using a wildcard. For example,

Access-Control-Allow-Origin: http://sample.com

Use ProxiesYou need to add this HTTP response to the third-party server. Adding such a header in the response is crucial because, without this, it will not be possible for your application to access the static files, resulting in script errors.

Let’s say, for some reason, you can't modify the HTTP header sent by the third-party server. In such cases, you can use web proxies to get around the problem. Once you set up a web proxy, you can send requests to the proxy instead of a third-party server. The proxy is usually hosted on the same domain.

The proxy forwards the request to a third-party server, fetches the script, and serves it back to the website. In this way, the web proxy acts as an intermediary between the application and a third-party server.

There are some open-source proxies available on the web, such as CORS Anywhere. However, use these services only in the development phase. Make sure to never use an open-source CORS proxy on a production application. They have high security risks.

Script Errors on Different Browsers

Script errors vary based on the browser. They may or may not affect the website experiences of the users. The solutions that we have provided above work for the following versions of popular web browsers:

Here, Firefox has a slightly different behavior at run time. It provides the script errors to the onerror callback without blocking it, even if that error comes from a third-party server. At the same time, if there is no CORS header, it will block the syntax errors from the cross-origin scripts.

Also, there are chances that Internet Explorer with version less than ten will report all the available data, which is a security risk nowadays. They have solved this issue by hiding the information if it's from a third-party script from Internet Explorer 11 onwards.

Stop Script Errors in Their Tracks

Script errors are a special kind of error that you get when using any third-party scripts. It can be problematic if you have your custom scripts, and this error might break the functionality of your application. Facing such script errors can bring a bad developer experience while debugging. In addition, it may be a pain to understand where it went wrong if you're using many third-party scripts. So, it's essential to address this issue with proper monitoring solutions.

Luckily, we have APM tools to capture such errors with a detailed stack trace and error message that helps the developer track down the code’s issue. You can try Scout for a 14-day free trial (no credit card required).

For more in-depth content around web development and a reliable tool for optimizing your application’s performance, navigate our blog and feel free to explore Scout APM with a free 14-day trial!