Simple, scripted, or scripted API (non-ping) errors

Problem

Your New Relic Synthetics Simple, Scripted, or Scripted API (non-ping) monitor reported an error, but the application appears to have loaded correctly. For ping and simple monitor errors, see non-scripted monitor errors.

Solutions

Below are some of the most common non-ping monitor error messages.

Simple or scripted browser errors

Element A is not clickable at point (X, Y). Other element would receive the click: Element B

Problem

The Synthetics script is attempting to .click() an element (Element A) at point (X,Y), but another element (Element B) is obscuring the target element.

Solution

Set a custom wait time, allowing time for a specific condition to be met. In this case, until the loading animation is no longer visible:

.then(function() {
    return $browser.wait($driver.until.elementIsNotVisible($browser.findElement($driver.By.id('LOADING'))), 10000);
})

Alternatively, you can set a custom sleep delay using $browser.sleep(sleeptime_ms), stalling script execution for a specified amount of time. As this is a fixed amount of wait-time, which does not account for increased network latency or degraded site performance, we recommend using the .wait() function instead.

Note: This will not correct .click() issues caused by sticky headers or footers. In these instances, you may need to scroll manually to bring the target into view.

Cause

This happens if the target element, at the time of the .click() function, is obscured by:

  • A loading overlay, modal, or pop-up
  • An animation that reveals the target element
  • A sticky header or footer
Error: element not visible

Problem

The targeted element is not visible to the Selenium WebDriver.

Solution

Verify that the targeted element does not have the CSS properties of display: none or visibility: hidden applied.

Cause

Any element that has a CSS property of display: none or visibility: hidden will not be found by the Selenium WebDriver, as the script will only look for elements that are actually visible to a user.

Error: no such element: Unable to locate element: <LOCATOR>

Problem

The Selenium WebDriver was unable to find this element in the visible DOM.

Solution

To resolve this problem:

  • Confirm that the element locator being used for the target element is accurate. Avoid using By.XPath where possible as it is rigidly tied to the page’s DOM structure, and can easily become out-of-date when there are updates on the page.
  • If element is in an iframe, use $browser.switchTo().frame(<index or element reference>.

See the Selenium documentation for more information on switchTo() and TargetLocator() functions.

Cause

Common reasons for this error include:

  • The targeted element is unable to be located by functions such as:
    • $browser.findElement(locator: $driver.Locator) or
    • $browser.waitForAndFindElement(locator: $driver.Locator [, timeout: number

    This may be due to a timing issue. For example, the WebDriver is attempting to locate the element before the page has been loaded.

  • Element is in an iframe, which is a separate document context.
JobTimeoutError: Job timed-out after 180s

Problem

The scripted monitor run reached the 180 second non-configurable timeout threshold, and the run was terminated.

Solution

If this is a frequent error, consider breaking up the scripted tasks into a separate scripted monitors.

If it appears that a specific task is causing the job to wait an unacceptable amount of time, consider changing the method by which you’re accomplishing that task. For example, changing $browser.findElement(locator: $driver.Locator) to $browser.waitForAndFindElement(locator: $driver.Locator [, timeout: number) would assign the task its own configurable timeout.

If you have multiple steps where the $browser.waitForAndFindElement(locator, timeout) function is called, ensure that the the sum of the provided timeouts to these steps does not exceed 180 seconds. If you’re finding it difficult to accomplish this, then that is a sign that the monitor should probably be broken up into separate monitor scripts.

Cause

All Synthetics scripted monitors have a non-configurable maximum global 180s timeout for running a script.

If a script has not completed after 180 seconds, the job is terminated. If this happens consistently it could be a sign of a script that is taking too long to complete, or that the job is waiting an extended period of time while attempting to perform a scripted task.

NetworkError: Monitor produced no traffic

Problem

The API test or scripted browser monitor appears to be running but is returning this error.

Solution

Ensure that $http.get() or $browser.get() are being called appropriately and are generating traffic.

For Scripted API monitors, if you are using a request option to spin up an un-instrumented HTTP agent under the hood, specify one of our instrumented HTTP agents using either of the agent request options below:

  • $globalAgents.http
  • $globalAgents.https

Example:

var options = {
    uri: 'https://www.newrelic.com',
    agent: $globalAgents.https,
    agentOptions: {
        'rejectUnauthorized': false
    },
    strictSSL: false
};

function callback(err, res, body) { ...
};

$http.get(options, callback);

Cause

This occurs in scripted monitor runs when the HTTP client ($http in Scripted API monitors) or Chrome browser ($browser in Scripted Browser monitors) is not used to generate HTTP traffic.

In some cases, certain request options in API monitors may force a new HTTP agent, one that is not instrumented by Synthetics, to be used to collect HTTP traffic.

ReferenceError: $network is not defined

Problem

The $network object used for setting monitor proxies is not available for that monitor’s runtime.

Solution

If your monitor was created before the 0.4.0 runtime release, create a new monitor to take advantage of the latest runtime. Your monitor’s current runtime version is shown at the top of the Monitor Settings page.

For more information, see Scripted monitor version runtime environments.

Cause

This error occurs when attempting to use $network on a monitor with a runtime at or below 0.2.2. Proxying monitor traffic was introduced in monitor runtime version 0.4.0, causing this method to be evaluated as undefined on earlier monitor runtimes.

ScriptTimeoutError

Problem

This error indicates that the job has reached the Docker container timeout threshold, and the script was terminated.

Solution

If this is a frequent error, consider breaking up the scripted tasks into a separate scripted monitors.

If it appears that a specific task is causing the job to wait an unacceptable amount of time, consider changing the method by which you’re accomplishing that task. For example, changing $browser.findElement(locator: $driver.Locator) to $browser.waitForAndFindElement(locator: $driver.Locator [, timeout: number) would assigned the task its own configurable timeout.

If you have multiple steps where the $browser.waitForAndFindElement(locator, timeout) function is called, ensure that the the sum of the provided timeouts to these steps does not exceed 180 seconds. If you’re finding it difficult to accomplish this, then that is a sign that the monitor should probably be broken up into separate monitor scripts.

Cause

All Synthetics scripted monitors have a non-configurable maximum global 180s timeout for running a script.

If a script has not completed after 180 seconds, the job is terminated. If this happens consistently it could be a sign of a script that is taking too long to complete, or that the job is waiting an extended period of time while attempting to perform a scripted task.

StaleElementReferenceError: element is not attached to the page document

Problem

The target page has loaded, but there was a change to an element between the execution of an element locator and an action being executed on the element.

Solution

Set your scripted browser to wait until the page is settled before performing a findElement() action. This can be accomplished by setting a custom wait time, using the $browser.wait(fn, timeout) function prior to the findElement call, to wait for a condition that indicates a settled page state. This will make it less likely for DOM manipulation to cause a reference to go stale.

Alternatively, you can set a custom sleep delay using $browser.sleep(sleeptime_ms), stalling script execution for a specified amount of time. As this is a fixed amount of wait-time, which does not account for increased network latency or degraded site performance, we recommend using the .wait() function instead.

Cause

This error typically happens when the script attempts to .click() an element after using either the findElement() or waitForAndFindElement() function.

If the DOM has changed between when the element locator was generated and the action was executed against the element, this error will occur because the actual element has changed.

For example: the findElement() function is used to generate an element reference while the page’s script is actively manipulating the DOM. The DOM is then changed, causing the previously generated reference to become stale. The now out-of-date reference is used in an attempt to perform a .click() action, resulting in this monitor failure.

For more information, see the Selenium documentation on Stale Element Reference Exceptions.

TaskTimedOut: task timed-out waiting for element to be located using: <LOCATOR>

Problem

The waitForAndFindElement(<locator>, <timeout>) function failed to locate an element within the provided timeout.

Solution

Confirm that the element locator being used for the target element is accurate. Avoid using By.XPath() where possible, as it is rigidly tied to the page’s DOM structure and can easily become out-of-date when there are updates on the page.

Cause

The target element did not exist on the page when the waitForAndFindElement(<locator>, <timeout>) function was called. This may be caused by the target page not being in the expected state.

Common reasons for this error include:

  • There is a legitimate issue with the target site.
  • The element locator being used is incorrect.
  • The target site has changed, requiring the revision of the Synthetics script.
  • The previous action in the script did not successfully complete, causing the page to be in an unexpected state when the subsequent waitForAndFindElement() call was initiated.
TimeoutError: page load timed-out

Problem

The target page loaded successfully, but returned the error:

TimeoutError: Page load timed-out (unable to finish all network requests on time)

Solution

If the failures began suddenly, investigate any requests that could be blocking or delaying the page load event. If you are unsure which request is causing the error, use the timeline view to identify any long running HTTP requests.

If the page is frequently unable to fully load within the current timeout, set a custom page load timeout using the $browser.manage().timeouts().pageLoadTimeout(ms: number) function.

Cause

The target page loaded successfully, but the page load event was not fired within the page load timeout set in the .pageLoadTimeout() function.

There are a number of reasons you could see this error message, including:

  • A blocked resource request on the page held up the page load.
  • A resource request processed slower than normal due to an underlying network issue.
  • A dependent resource on the page blocked the iframe load event.
TypeError: $browser.isElementPresent is not a function

Problem

The function isElementPresent(), used by Synthetics monitors with a runtime >= 0.5.0, has been deprecated in Selenium 3.

Solution

To continue to use this function after depreciation you will need to create a custom version of this function, such as:

return $browser.findElements(ele).then(function(found) {
    return found.length > 0;
});
}

Example usage, which would return true:

$browser
    .get("https://www.newrelic.com")
    .then(function() {
        return isElementPresent($driver.By.id("nav_signup"));
    })
    .then(function(found) {
        return console.log(found);
    });

Cause

This can occur when attempting to use a Synthetics Scripted Browser monitor script from an older monitor ( <= 0.4.1 runtime) with a newer Synthetics monitor ( >= 0.5.0) runtime.

Scripted API monitor errors

JobTimeoutError: Job timed-out after 180s

Problem

The scripted monitor run reached the 180 second non-configurable timeout threshold, and the run was terminated.

Solution

If this is a frequent error, consider breaking up the scripted tasks into a separate scripted monitors.

If it appears that a specific task is causing the job to wait an unacceptable amount of time, consider changing the method by which you’re accomplishing that task. For example, changing $browser.findElement(locator: $driver.Locator) to $browser.waitForAndFindElement(locator: $driver.Locator [, timeout: number) would assign the task its own configurable timeout.

If you have multiple steps where the $browser.waitForAndFindElement(locator, timeout) function is called, ensure that the the sum of the provided timeouts to these steps does not exceed 180 seconds. If you’re finding it difficult to accomplish this, then that is a sign that the monitor should probably be broken up into separate monitor scripts.

Cause

All Synthetics scripted monitors have a non-configurable maximum global 180s timeout for running a script.

If a script has not completed after 180 seconds, the job is terminated. If this happens consistently it could be a sign of a script that is taking too long to complete, or that the job is waiting an extended period of time while attempting to perform a scripted task.

NetworkError: Monitor produced no traffic

Problem

The API test or scripted browser monitor appears to be running but is returning this error.

Solution

Ensure that $http.get() or $browser.get() are being called appropriately and are generating traffic.

For Scripted API monitors, if you are using a request option to spin up an un-instrumented HTTP agent under the hood, specify one of our instrumented HTTP agents using either of the agent request options below:

  • $globalAgents.http
  • $globalAgents.https

Example:

var options = {
    uri: 'https://www.newrelic.com',
    agent: $globalAgents.https,
    agentOptions: {
        'rejectUnauthorized': false
    },
    strictSSL: false
};

function callback(err, res, body) { ...
};

$http.get(options, callback);

Cause

This occurs in scripted monitor runs when the HTTP client ($http in Scripted API monitors) or Chrome browser ($browser in Scripted Browser monitors) is not used to generate HTTP traffic.

In some cases, certain request options in API monitors may force a new HTTP agent, one that is not instrumented by Synthetics, to be used to collect HTTP traffic.

ReferenceError: $network is not defined

Problem

The $network object used for setting monitor proxies is not available for that monitor’s runtime.

Solution

If your monitor was created before the 0.4.0 runtime release, create a new monitor to take advantage of the latest runtime. Your monitor’s current runtime version is shown at the top of the Monitor Settings page.

For more information, see Scripted monitor version runtime environments.

Cause

This error occurs when attempting to use $network on a monitor with a runtime at or below 0.2.2. Proxying monitor traffic was introduced in monitor runtime version 0.4.0, causing this method to be evaluated as undefined on earlier monitor runtimes.

ScriptTimeoutError

Problem

This error indicates that the job has reached the Docker container timeout threshold, and the script was terminated.

Solution

If this is a frequent error, consider breaking up the scripted tasks into a separate scripted monitors.

If it appears that a specific task is causing the job to wait an unacceptable amount of time, consider changing the method by which you’re accomplishing that task. For example, changing $browser.findElement(locator: $driver.Locator) to $browser.waitForAndFindElement(locator: $driver.Locator [, timeout: number) would assigned the task its own configurable timeout.

If you have multiple steps where the $browser.waitForAndFindElement(locator, timeout) function is called, ensure that the the sum of the provided timeouts to these steps does not exceed 180 seconds. If you’re finding it difficult to accomplish this, then that is a sign that the monitor should probably be broken up into separate monitor scripts.

Cause

All Synthetics scripted monitors have a non-configurable maximum global 180s timeout for running a script.

If a script has not completed after 180 seconds, the job is terminated. If this happens consistently it could be a sign of a script that is taking too long to complete, or that the job is waiting an extended period of time while attempting to perform a scripted task.

SyntaxError: Unexpected token <

Problem

JSON.parse() was passed a string that begins with the < character and is likely HTML, instead of JSON.

Solution

Ensure the target endpoint is returning the expected response body. You can do this by logging the response body in the callback, before attempting to parse.

Example:

$http.get('http://www.newrelic.com', function(error, response, body) {
  if (error) {
      throw new Error(error);
  }

  console.log(body);    // Log HTML response body, don't parse as JSON

});

Depending on the target API endpoint, you may need to include specific request headers to ensure that JSON is returned.

Cause

The script is attempting to use JSON.parse() on a response body after a request is made and is expecting the endpoint to return JSON, but HTML was returned instead.

SyntaxError: Unexpected token u in JSON at position 0

Problem

JSON.parse() was passed an undefined parameter, but expected a JSON string.

Solution

Troubleshoot the cause of the request error. Details on what is causing request errors can be found in the error object passed to the request callback function.

Example:

$http.get('http://www.newrelic.com', function(error, response, body) {
  if (error) {
      throw new Error(error);
  }

  var bodyJson = JSON.parse(body);
  console.log(bodyJson);           // Log response body

});

Cause

This can occur in Scripted API monitors when a performing an API request, then attempting to parse the request response within the callback function. The response body is passed to JSON.parse() without checking if the response body is undefined first.

An undefined response body is often caused by a request error. If there is no error handling to prevent code that parses the response body, this monitor failure will occur.

TypeError: Cannot read property 'statusCode' of undefined

Problem

The response object (and thus response.statusCode) in an API request callback is undefined.

Solution

Troubleshoot the cause of the request error. Details on what is causing request errors can be found in the error object passed to the request callback function.

Example:

$http.get('http://www.newrelic.com', function(error, response, body) {
    if (error) {
        throw new Error(error);
    }
    console.log(response.statusCode);
});

Cause

This error occurs when there was an error completing the API request (e.g., unable to reach server, unable to resolve DNS). In these instances, the request was not completed so the response object in the callback function arguments is undefined.

If there is no error handling to prevent code that checks response status code, this monitor failure will occur.

Recommendations for learning more: