Устранение неполадок с ошибками выполнения правил JavaScript

Вы просматриваете документацию по Apigee Edge.
Перейдите к документации по Apigee X.
Информация

ScriptExecutionFailed

Код ошибки

steps.javascript.ScriptExecutionFailed

Тело ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of javascript_policy_name failed with error: error_type: error_description. (javascript_source_file_name)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Типы ошибок и возможные причины

Правило JavaScript может вызывать различные ошибки ScriptExecutionFailed. В таблице ниже перечислены некоторые распространенные ошибки.

Тип ошибки Cause
Ошибка диапазона Если вы используете число, которое выходит за пределы допустимых значений, возникает ошибка RangeError.
Ошибка при создании отпечатка Ошибка ReferenceError возникает, если вы используете (ссылаетесь на) переменную, которая не была объявлена.
Синтаксическая ошибка SyntaxError возникает, если вы пытаетесь выполнить код с синтаксической ошибкой.
Ошибка типа TypeError возникает, если вы используете операцию, которая не соответствует ожидаемым типам.
Ошибка URI Если в функции URI используются недопустимые символы, возникает ошибка URIError.

Ошибка диапазона

Ошибка типа RangeError возникает, когда вы выполняете операцию со значением или передаете значение функции, которое не входит в набор или диапазон допустимых значений.

Например, эта ошибка возникает в следующих случаях:

  1. Если вы используете недопустимую дату, например 31 сентября 2018 г., с некоторыми API даты.
  2. Если вы передаете недопустимое значение числовым методам, например Number.toPrecision(), Number.tofixed() или Number.toExponential(). Например, если вы передадите в метод Number.toPrecision() большое значение, например 400 или 500, то увидите ошибку диапазона.
  3. Если вы создаете массив недопустимой длины.

Тело ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of javascript_policy_name failed with error: Javascript runtime error: \"RangeError: error_description. (javascript_source_file_name:line_number)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Примечание. Диагностика и устранение ошибок диапазона зависят от точного сообщения об ошибке, которое выдает правило JavaScript. Ниже приведены два примера.

Пример 1. Недопустимая дата

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of ParseDate failed with error: Javascript runtime error: \"RangeError: Date is invalid. (ParseDate.js:2)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правило JavaScript, его исходный файл, номер строки, в которой произошла ошибка, и описание ошибки. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в следующем коде faultstring название правила JavaScript – ParseDate, исходный файл JavaScript – ParseDate.js, номер строки, в которой произошла ошибка, – 2, а описание ошибки – Date is invalid:

    "faultstring": "Execution of ParseDate failed with error: Javascript runtime error: \"RangeError: Date is invalid. (ParseDate.js:2)\""
    
  2. Проверьте исходный файл JavaScript (определенный на шаге 1 выше) и убедитесь, что в строке, указанной в ошибке, используется действительная дата или что переменная, используемая в строке, содержит действительную дату. Если дата указана неверно, это и будет причиной ошибки.

    Ниже приведен пример исходного файла JavaScript, который приводит к этой ошибке:

    ParseDate.js

    var date = new Date('2018-09-31T11:19:08.402Z');
    date.toISOString();
    

    В этом примере в строке 2 используется переменная date. В исходном файле переменная date содержит недопустимую дату: 2018-09-31T11:19:08.402Z.. Эта дата недопустима, поскольку в сентябре нет 31 дня.

    Примечание. В этом примере используется формат ISO-8601: YYYY-MM-DDTHH:mm:ss.sssZ

Разрешение

При использовании API даты в коде JavaScript всегда указывайте действительную дату.

Чтобы исправить приведенный выше пример кода JavaScript, задайте дату как Sept 30 2018, как показано ниже:

var date = new Date('2018-09-30T11:19:08.402Z');
date.toISOString();

Пример 2. Недопустимое число, переданное в API точности

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of SetNumberPrecision failed with error: Javascript runtime error: "RangeError: Precision 400 out of range. (SetNumberPrecision.js:2)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правила JavaScript, исходный файл, номер строки, в которой произошла ошибка, и описание ошибки. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в следующем коде faultstring название правила JavaScript – SetNumberPrecision, исходный файл JavaScript – SetNumberPrecision.js, номер строки, в которой произошла ошибка, – 2, а описание ошибки – Precision 400 out of range..

    "faultstring": "Execution of SetNumberPrecision failed with error: Javascript runtime error: "RangeError: Precision 400 out of range. (SetNumberPrecision.js:2)\""
    
  2. Проверьте исходный файл JavaScript (определенный на шаге 1 выше). Если большое число, указанное в описании ошибки, используется в номере строки, то именно это и является причиной ошибки.

    Ниже приведен пример исходного файла JavaScript, который приводит к этой ошибке:

    SetNumberPrecision.js

    var number = 12.3456;
    var rounded_number = number.toPrecision(400);
    print("rounded_number = " + rounded_number);
    

    В этом примере обратите внимание, что в строке 2 используется большое значение 400. Поскольку вы не можете задать такую точность, появляется ошибка:

    "faultstring": "Execution of SetNumberPrecision failed with error: Javascript runtime error: "RangeError: Precision 400 out of range. (SetNumberPrecision.js:2)\""
    

Разрешение

Убедитесь, что число, используемое в методе toPrecision(), входит в набор допустимых значений.

Чтобы исправить проблему в приведенном выше примере кода JavaScript, задайте для количества значащих цифр значение 2, которое является допустимым:

var number = 12.3456;
var rounded_number = number.toPrecision(2);
print("rounded_number = " + rounded_number);

Ошибка ссылки

Ошибка типа ReferenceError возникает, когда в коде JavaScript используется (упоминается) или обрабатывается неопределенная переменная.

Тело ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of javascript_policy_name failed with error: Javascript runtime error: \"ReferenceError: variable_name is not defined. (javascript_source_file_name:line_number)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of ComputeTotalPrice failed with error: Javascript runtime error: \"ReferenceError: \"price\" is not defined. (ComputeTotalPrice.js:3)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правила JavaScript, исходный файл и номер строки, в которой упоминается неопределенная переменная. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в следующем коде faultstring название правила JavaScript – ComputeTotalPrice, соответствующий исходный файл – ComputeTotalPrice.js, номер строки, в которой произошла ошибка, – 3, а название неопределенной переменной – price..

    "faultstring": "Execution of ComputeTotalPrice failed with error: Javascript runtime error: \"ReferenceError: \"price\" is not defined. (ComputeTotalPrice.js:3)\""
    
  2. Проверьте номер строки в исходном файле JavaScript и убедитесь, что переменная, определенная на шаге 1, используется. Например, в приведенном ниже коде JavaScript в строке 3 упоминается неопределенная переменная price, которая соответствует значению faultstring:

    ComputeTotalPrice.js

    var item = context.getVariable("request.queryparam.item");
    var quantity = context.getVariable("request.queryparam.quantity");
    var totalprice = parseInt(quantity) * parseInt(price);
    context.setVariable("TotalPrice", totalprice);
    
    
  3. Проверьте, определена ли нужная переменная в коде JavaScript. Если переменная не определена, это и будет причиной ошибки.

    В приведенном выше примере скрипта используется необъявленная/неопределенная переменная price, поэтому вы увидите следующую ошибку:

    "faultstring": "Execution of ComputeTotalPrice failed with error: Javascript runtime error: \"ReferenceError: \"price\" is not defined. (ComputeTotalPrice.js:3)\""
    

Разрешение

Убедитесь, что все переменные, на которые ссылается код JavaScript, определены правильно.

Чтобы исправить проблему в приведенном выше примере кода JavaScript, определите переменную price до ее использования. Пример:

var item = context.getVariable("request.queryparam.item");
var quantity = context.getVariable("request.queryparam.quantity");
var price = context.getVariable("request.queryparam.price");
var totalprice = parseInt(quantity) * parseInt(price);
context.setVariable("TotalPrice", totalprice);

Синтаксическая ошибка

Ошибка типа SyntaxError возникает, когда движок JavaScript обнаруживает токены или порядок токенов, не соответствующие синтаксису языка, или когда в API синтаксического анализатора, например JSON/XML, передается входное значение недопустимого формата.

Например, если в качестве входных данных для API JSON.parse, используемого в правиле JavaScript, передается недопустимая или неправильно сформированная полезная нагрузка JSON, то возникает эта ошибка.

Тело ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of javascript_policy_name failed with error: Javascript runtime error: \"SyntaxError: error_description. (javascript_source_file_name:line_number)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of ParseJSONRequest failed with error: Javascript runtime error: \"SyntaxError: Unexpected token: <. (ParseJSONRequest.js:2)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правила JavaScript, исходный файл, номер строки, в которой произошла ошибка, и описание ошибки. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в следующем коде faultstring название правила JavaScript – ParseJSONRequest, исходный файл JavaScript – ParseJSONRequest.js, номер строки, в которой произошла ошибка, – 2, а описание ошибки – Unexpected token:

    "faultstring": "Execution of ParseJSONRequest failed with error: Javascript runtime error: \"SyntaxError: Unexpected token: <. (ParseJSONRequest.js:2)\""
    
  2. Проверьте строку 2 в исходном файле JavaScript (определенном на шаге 1 выше) и узнайте, какая операция выполняется. Если выполняется функция JSON.parse(), проверьте входной параметр, переданный ей. Если входной параметр недопустим или имеет неверный формат JSON, это и будет причиной ошибки.

    Вот пример кода JavaScript, который приводит к этой ошибке:

    var input = context.getVariable("request.content");
    var result = JSON.parse(input);
    

    В этом примере полезная нагрузка запроса (request.content), переданная в API Proxy, используется в качестве входных данных для функции JSON.parse().

    Вот пример вызова API, показывающий, как был передан запрос:

    curl -v "http://<org>-<env>.apigee.net/v1/js-demo" -H "Content-Type: application/json" -X POST -d '<city>Bangalore</city>'
    

    В приведенном выше запросе в прокси API <city>Bangalore</city> передается следующая полезная нагрузка XML: API JSON.parse ожидает получить действительный объект JSON, но вместо этого получает полезную нагрузку XML, поэтому возникает следующая ошибка:

    "Execution of ParseJSONRequest failed with error: Javascript runtime error: \"SyntaxError: Unexpected token: <. (ParseJSONRequest.js:2)\""
    

Разрешение

Убедитесь, что в API, используемые в коде JavaScript, передаются действительные входные данные.

Чтобы исправить проблему с примером правил, передайте действительный запрос полезной нагрузки JSON следующим образом:

curl -v "http://<org>-<env>.apigee.net/v1/js-demo" -H "Content-Type: application/json" -X POST -d '{"city" : "Bangalore"}'

Ошибка несоответствия типов

Ошибка TypeError возникает в следующих случаях:

  • Операнд или аргумент, переданный функции, несовместим с типом, ожидаемым оператором или функцией.
  • Функция вызывается для объекта null, undefined или неправильного объекта.
  • Свойство доступно из нулевого, неопределенного или неправильного объекта.

Например, возникает ошибка типа:

  • Если вы попытаетесь вызвать функцию toUpperCase() для числа. Это связано с тем, что функцию toUpperCase() можно вызывать только для строковых объектов.
  • Если вы попытаетесь прочитать свойство из объекта со значением null или undefined.

Тело ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of javascript_policy_name failed with error: Javascript runtime error: \"TypeError: error_description. (javascript_source_file_name:line_number)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Пример 1. Вызов функции для неправильного объекта

Если вы попытаетесь вызвать функцию для неподдерживаемого объекта, появится эта ошибка. Например, если вы попытаетесь вызвать функцию toUpperCase() для номера, появится ошибка. Это связано с тем, что функцию toUpperCase() можно вызывать только для строковых объектов.

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of ConvertToUpperCase failed with error: Javascript runtime error: \"TypeError: Cannot find function toUpperCase in object 100. (ConvertToUpperCase.js:2)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правила JavaScript, исходный файл, номер строки, в которой произошла ошибка, и описание ошибки. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в следующем коде faultstring название правила JavaScript – ConvertToUpperCase, исходный файл – ConvertToUpperCase.js, номер строки – 2, а описание ошибки – **Cannot find function toUpperCase in object 100.

    "faultstring": "Execution of ConvertToUpperCase failed with error: Javascript runtime error: \"TypeError: Cannot find function toUpperCase in object 100. (ConvertToUpperCase.js:2)\""
    

    Описание ошибки указывает, что вы вызываете функцию toUpperCase() для объекта, числовое значение которого равно 100.

  2. Проверьте исходный файл JavaScript и убедитесь, что вы вызываете функцию toUpperCase() для объекта, числовое значение которого равно 100, в строке 2 (определенной на шаге 1 выше). Если да, то это и есть причина ошибки.

    Ниже приведен пример исходного файла JavaScript, который приводит к этой ошибке:

    ConvertToUpperCase.js

    var number = 100;
    var result = number.toUpperCase();
    

    В приведенном выше коде JavaScript переменной number присвоено значение 100. Затем функция toUpperCase()( вызывается для объекта number. Поскольку функцию toUpperCase() можно вызывать только для строковых объектов, вы получите ошибку:

    "Execution of ConvertToUpperCase failed with error: Javascript runtime error: \"TypeError: Cannot find function toUpperCase in object 100. (ConvertToUpperCase.js:2)\""
    

Разрешение

Всегда используйте функции, такие как toUpperCase(), для допустимых объектов.

Чтобы исправить приведенный выше пример, можно создать строковую переменную, а затем вызвать функцию toUpperCase() для строки:

var text = "Hello Apigee !";
var result = text.toUpperCase();

Пример 2. Невозможно прочитать свойство из неопределенного объекта

Если вы попытаетесь получить доступ к свойству из неопределенного объекта, появится эта ошибка. Например, эта ошибка может возникнуть, когда вы пытаетесь получить доступ к данным из объекта в массиве, но объект не определен. Подробные сведения приведены ниже.

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of ParseJSONResponse failed with error: Javascript runtime error: \"TypeError: Cannot read property \"length\" from undefined. (ParseJSONResponse.js:7)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правила JavaScript, исходный файл, номер строки, в которой произошла ошибка, и описание ошибки. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в следующем коде faultstring название правила – ParseJSONResponse, исходный файл – ParseJSONResponse.js, номер строки – 6, а описание ошибки – Cannot read property "length" from undefined.

    "faultstring": "Execution of ParseJSONResponse failed with error: Javascript runtime error: \"TypeError: Cannot read property \"length\" from undefined. (ParseJSONResponse.js:6)\""
    

    Ошибка указывает на то, что свойство length нельзя прочитать из неопределенного объекта.

  2. Проверьте номер строки в исходном файле JavaScript (определенном на шаге 1 выше) и убедитесь, что у объекта допустимое значение или он не определен. Чтобы понять, как был определен или получен тот или иной объект и почему он считается неопределенным, вам может потребоваться прочитать и понять весь исходный файл. Если вы обнаружите, что определенный объект действительно не определен и вы пытаетесь получить доступ к свойству length из него, то это и будет причиной ошибки.

    Чтобы лучше понять эту проблему, рассмотрим пример.

    1. Предположим, что вы получили следующий ответ JSON от внутреннего сервера:

      {
          "cars": [
             { "name":"Toyota", "count": 150 }
             { "name":"Honda", "count": 100 },
             { "name":"Ford", "count": 75 }
          ]
      }
      
    2. Ниже приведен пример исходного файла JavaScript, который анализирует этот ответ JSON и приводит к упомянутой выше ошибке:

      ParseJSONResponse.js

      // Get the JSON response
      var jsonData = context.getVariable("response.content");
      print (jsonData);
      
      // Read the cars array
      for (var i = 0; i < jsonData.cars.length; i++)
        {
        print("name = " + jsonData.cars[i].name);
        print("count = " + jsonData.cars[i].count);
        }
      
    3. Внимательно изучив код JavaScript, вы увидите, что в строке 2 значение response.content считывается и сохраняется в переменной jsonData как обычная строка (в кавычках).

    4. Поскольку jsonData – обычная строка, при попытке получить доступ к cars из jsonData (jsonData.cars) будет возвращено значение undefined.

    5. После этого при попытке прочитать свойство length из jsonData.cars, которое не определено, вы получите ошибку:

      "faultstring": "Execution of ParseJSONResponse failed with error: Javascript runtime error: \"TypeError: Cannot read property \"length\" from undefined. (ParseJSONResponse.js:6)\""
      

Разрешение

Всегда считывайте данные JSON как объект JSON, используя соответствующие JSON API.

Чтобы исправить приведенный выше пример кода JavaScript, используйте функцию JSON.parse() для объекта response.content, чтобы получить его в виде объекта JSON. После этого вы сможете получить доступ к массиву cars и успешно перебрать его.

// Get the JSON response
var data = context.getVariable("response.content");
var jsonData = JSON.parse(data);
print (jsonData);

// Read the cars array
for (var i = 0; i < jsonData.cars.length; i++)
{
    print("name = " + jsonData.cars[i].name);
    print("count = " + jsonData.cars[i].count);
}

Ошибка URI

Ошибка типа URIError возникает, если в функции URI используются недопустимые символы. Например, если передать URI с символом процента в функции decodeURI или decodeURIComponent, появится эта ошибка.

Тело ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of javascript_policy_name failed with error: Javascript runtime error: \"URIError: error_description. (javascript_source_file_name:line_number)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

Пример текста ответа с ошибкой

{
    "fault": {
        "faultstring": "Execution of URIDecode failed with error: Javascript runtime error: \"URIError: Malformed URI sequence. (URIDecode.js:2)\"",
        "detail": {
            "errorcode": "steps.javascript.ScriptExecutionFailed"
        }
    }
}

диагностика;

  1. Определите правило JavaScript, его исходный файл, номер строки, в которой произошла ошибка, и описание ошибки. Всю эту информацию можно найти в элементе faultstring ответа об ошибке. Например, в приведенной ниже строке faultstring название правила JavaScript – URIDecode</code, исходный файл JavaScript – URIDecode.js, номер строки – 2, а описание ошибки – Malformed URI sequence:

    "faultstring": "Execution of URIDecode failed with error: Javascript runtime error: \"URIError: Malformed URI sequence. (URIDecode.js:2)\""
    

    Описание ошибки указывает, что в строке 2 файла URIDecode.js используется неправильная последовательность URI.

  2. Проверьте исходный файл JavaScript и убедитесь, что аргумент, переданный любой из функций URI, не содержит недопустимых символов. Если да, то это и есть причина ошибки.

    Вот пример исходного файла JavaScript, который приводит к этой ошибке:

    URIDecode.js

    var str = "75%-Completed";
    var decoded_str = decodeURIComponent(str);
    context.setVariable("decoded_str", decoded_str);
    

    В приведенном выше примере кода JavaScript переменная str, переданная в decodeURIComponent(), содержит символ процента, который считается недопустимым. В результате возникает ошибка:

    "Execution of URIDecode failed with error: Javascript runtime error: \"URIError: Malformed URI sequence. (URIDecode.js:2)\""
    

Разрешение

Убедитесь, что все символы, используемые в функциях URI, допустимы.

Чтобы исправить проблему с приведенным выше примером кода JavaScript, закодируйте символ процента. Пример: %25.

var str = "75%25-Completed";
var decoded_str = decodeURIComponent(str);
context.setVariable("decoded_str", decoded_str);