Problem
Your New Relic's synthetic 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
Problem
The synthetic 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.
Dica
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
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.
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>
.Dica
See the Selenium documentation for more information on
switchTo()
andTargetLocator()
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.
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 synthetic 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.
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 synthetic monitoring, to be used to collect HTTP traffic.
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's settings.
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.
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 synthetic 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.
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.
Dica
For more information, see the Selenium documentation on Stale Element Reference Exceptions.
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.
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.
Problem
The function isElementPresent()
, used by synthetic 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 scripted browser monitor script from an older monitor ( <= 0.4.1 runtime) with a newer monitor ( >= 0.5.0) runtime.
Scripted API monitor errors
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 synthetic monitoring, to be used to collect HTTP traffic.
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.
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.
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.
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 (for example, 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.