Solución de errores en el entorno de ejecución de la política de JavaScript

Estás viendo la documentación de Apigee y Apigee Hybrid.
Consulta la documentación de Apigee Edge.

ScriptExecutionFailed

Código de error

steps.javascript.ScriptExecutionFailed

Cuerpo de la respuesta de error

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

Tipos de errores y posibles causas

La política de JavaScript puede arrojar muchos tipos diferentes de errores de ScriptExecutionFailed. En la siguiente tabla se enumeran algunos de los errores más frecuentes:

Tipo de error Causa
Error de rango Se genera un RangeError si usas un número que está fuera del rango de valores válidos.
Error de referencia Se genera un ReferenceError si usas (haces referencia a) una variable que no se declaró.
Error de sintaxis Se produce un SyntaxError si intentas evaluar el código con un error de sintaxis.
Error de tipo Se muestra un TypeError si usas una operación que se encuentra fuera del rango de tipos esperados.
Error de URI Se genera un URIError si usas caracteres no válidos en una función de URI.

Error de rango

El tipo de error RangeError se genera cuando operas en un valor o pasas un valor a una función que no está en el conjunto o el rango de valores permitidos.

Por ejemplo, este error se genera en las siguientes circunstancias:

  1. Si usas una fecha no válida, como el 31 de septiembre de 2018 con algunas de las API de fecha.
  2. Si pasas un valor no válido a métodos numéricos, como Number.toPrecision(), Number.tofixed() o Number.toExponential(). Por ejemplo, supongamos que pasas un valor grande, como 400 o 500 en el método Number.toPrecision(), verás un error de rango.
  3. Si creas un arreglo con una longitud no válida.

Cuerpo de la respuesta de error

{
    "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"
        }
    }
}

Nota: El diagnóstico y la resolución de los errores de rango dependen del mensaje de error exacto que muestra la política de JavaScript. A continuación, se describen algunos ejemplos a modo de referencia.

Ejemplo 1: fecha no válida

Cuerpo de la respuesta de error de ejemplo

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

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen, el número de línea donde ocurrió el error y la descripción del error. Puedes encontrar esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en la siguiente faultstring, el nombre de la política de JavaScript es ParseDate, el archivo de origen de JavaScript es ParseDate.js, el número de línea en el que se produjo el error es 2 y la descripción del error es Date is invalid:

    "faultstring": "Execution of ParseDate failed with error: Javascript runtime error: \"RangeError: Date is invalid. (ParseDate.js:2)\""
    
  2. Examina el archivo fuente de JavaScript (identificado en el paso 1 anterior) y comprueba si hay una fecha no válida en el número de línea especificado en el error o si la variable utilizada en el número de línea tiene una fecha no válida. Si se utiliza una fecha no válida, esa es la causa del error.

    A continuación, te mostramos un archivo de origen de JavaScript de muestra que genera este error:

    ParseDate.js

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

    En este ejemplo, hay una variable date usada en el número de línea 2. Cuando examinas el archivo de origen, puedes ver que la variable date está configurada con una fecha no válida: 2018-09-31T11:19:08.402Z. Esta fecha no es válida porque septiembre no tiene 31 días.

    Nota: El formato ISO-8601 que se usa en este ejemplo es YYYY-MM-DDTHH:mm:ss.sssZ

Solución

Asegúrate de usar siempre una fecha válida mientras usas las API de fecha en el código de JavaScript.

Para corregir el código de JavaScript de ejemplo que se muestra arriba, puedes establecer la fecha como Sept 30 2018 como se muestra a continuación:

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

Ejemplo 2: Se pasó un número no válido a las API de precisión

Cuerpo de la respuesta de error de ejemplo

{
    "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"
        }
    }
}

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen, el número de línea donde ocurrió el error y la descripción del error. Puedes encontrar esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en el siguiente faultstring, el nombre de la política de JavaScript es SetNumberPrecision, el archivo de origen de JavaScript es SetNumberPrecision.js, el número de línea donde se produjo el error es 2 y la descripción del error es 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. Examina el archivo fuente de JavaScript (identificado en el paso nº 1 anterior). Si el número grande mencionado como parte de la descripción del error se utiliza en el número de línea específico, esa es la causa del error.

    A continuación, te mostramos un archivo de origen de JavaScript de muestra que genera este error:

    SetNumberPrecision.js

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

    En este ejemplo, observe que se utiliza un valor grande de 400 en el número de línea 2. Debido a que no puedes establecer la precisión en una cantidad de dígitos tan elevada, obtienes el siguiente error:

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

Solución

Asegúrate de que el número que se usa en el método toPrecision() esté dentro del conjunto de valores permitidos.

Para solucionar el problema con el ejemplo de JavaScript descrito anteriormente, establece la cantidad de dígitos significativos en 2, lo que es válido:

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

Error de referencia

El tipo de error ReferenceError se muestra cuando se usa (se hace referencia a) o se opera una variable no definida en tu JavaScript.

Cuerpo de la respuesta de error

{
    "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"
        }
    }
}

Cuerpo de la respuesta de error de ejemplo

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

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen y el número de línea donde se hace referencia a la variable indefinida. Puedes encontrar esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en el siguiente faultstring, el nombre de la política de JavaScript es ComputeTotalPrice, el archivo de origen correspondiente es ComputeTotalPrice.js, el número de línea en el que se produjo el error es 3 y el nombre de la variable no definido es price.

    "faultstring": "Execution of ComputeTotalPrice failed with error: Javascript runtime error: \"ReferenceError: \"price\" is not defined. (ComputeTotalPrice.js:3)\""
    
  2. Examina el número de línea del archivo de origen de JavaScript y verifica si se hace referencia a la variable no definida identificada en el paso n.º 1. Por ejemplo, el siguiente código de JavaScript hace referencia a la variable sin definir price en la línea 3, que coincide con lo que hay en la 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. Verifica si la variable específica se define en el código de JavaScript. Si la variable no está definida, esa es la causa del error.

    En la secuencia de comandos de ejemplo anterior, se usa la variable price no declarada o definida. Por lo tanto, verás el siguiente error:

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

Solución

Asegúrate de que todas las variables a las que se hace referencia en el código JavaScript estén definidas correctamente.

Para corregir el problema con el código JavaScript de ejemplo anterior, define el precio de la variable antes de usarlo. Por ejemplo:

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);

Se produjo un error de sintaxis

El tipo de error SyntaxError se genera cuando el motor de JavaScript encuentra tokens o un orden de tokens que no se ajusta a la sintaxis del lenguaje, o cuando se pasa una entrada con formato no válido a las API del analizador, como el análisis JSON/XML.

Por ejemplo, si la carga útil JSON no válida o con formato incorrecto se pasa como la entrada a la API JSON.parse usada en la política de JavaScript, verás este error.

Cuerpo de la respuesta de error

{
    "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"
        }
    }
}

Cuerpo de la respuesta de error de ejemplo

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

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen, el número de línea donde ocurrió el error y la descripción del error. Puedes encontrar esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en la siguiente faultstring, el nombre de la política de JavaScript es ParseJSONRequest, el archivo de origen de JavaScript es ParseJSONRequest.js, el número de línea en el que se produjo el error es 2 y la descripción del error es Unexpected token:

    "faultstring": "Execution of ParseJSONRequest failed with error: Javascript runtime error: \"SyntaxError: Unexpected token: <. (ParseJSONRequest.js:2)\""
    
  2. Examine el número de línea 2 en el archivo fuente de JavaScript (identificado en el paso nº 1 anterior) y verifique qué operación se está realizando. Si se está ejecutando una función JSON.parse(), verifica el parámetro de entrada que se le pasó. Si el parámetro de entrada no es válido o tiene un formato JSON incorrecto, esa es la causa del error.

    A continuación, se muestra un ejemplo de código de JavaScript que lleva a este error:

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

    En este ejemplo, la carga útil de la solicitud (request.content) que pasó al proxy de API se usa como entrada a la función JSON.parse().

    A continuación, la llamada a la API de muestra que muestra cómo se pasó la solicitud:

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

    En la solicitud anterior, se envía la siguiente carga útil XML al proxy de API <city>Bangalore</city>. La API de JSON.parse espera que se pase un JSON válido, pero como se pasa una carga útil de XML, falla con el error que se muestra a continuación:

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

Solución

Asegúrate de pasar una entrada válida a las API de análisis que se usan en el código de JavaScript.

Para solucionar el problema con la política de muestra que mencionamos antes, pasa una solicitud de carga útil JSON válida de la siguiente manera:

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

Error de tipo

El tipo de error TypeError aparece cuando ocurre lo siguiente:

  • Un operando o argumento pasado a una función no es compatible con el tipo que espera ese operador o función.
  • Una función se invoca en un objeto nulo, indefinido o incorrecto.
  • Se accede a una propiedad desde un objeto nulo, indefinido o incorrecto.

Por ejemplo, se muestra un error de tipo:

  • Si intentas invocar la función toUpperCase() en un número. Esto se debe a que la función toUpperCase() solo se puede invocar en objetos de string.
  • Si intentas leer una propiedad desde un objeto nulo o indefinido.

Cuerpo de la respuesta de error

{
    "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"
        }
    }
}

Ejemplo 1: Se invoca una función en el objeto incorrecto

Si intentas invocar una función en un objeto no admitido, se mostrará este error. Por ejemplo, si intentas invocar la función toUpperCase() en un número, obtendrás el error. Esto se debe a que la función toUpperCase() solo se puede invocar en objetos de string.

Cuerpo de la respuesta de error de ejemplo

{
    "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"
        }
    }
}

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen, el número de línea donde ocurrió el error y la descripción del error. Puedes encontrar esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en la siguiente faultstring, el nombre de la política de JavaScript es ConvertToUpperCase, el archivo de origen es ConvertToUpperCase.js, el número de línea es 2 y la descripción del error es **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)\""
    

    La descripción del error indica que estás invocando la función toUpperCase() en un objeto cuyo valor numérico es 100.

  2. Examina el archivo fuente de JavaScript y verifica si invocas la función toUpperCase() en un objeto cuyo valor numérico es 100 en la línea número 2 (identificado en el paso nº 1 anterior). Si es así, esa es la causa del error.

    A continuación, te mostramos un archivo de origen de JavaScript de muestra que genera este error:

    ConvertToUpperCase.js

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

    En el código JavaScript que se muestra arriba, la variable number está configurada con un valor de 100. Posteriormente, la función toUpperCase()( se invoca en el objeto numérico. Dado que la función toUpperCase() solo se puede invocar en objetos de string, obtienes el siguiente error:

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

Solución

Usa siempre funciones como toUpperCase() en objetos válidos.

Para corregir el ejemplo anterior, puedes crear una variable de string y, luego, invocar la función toUpperCase() en una string:

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

Ejemplo 2: No se puede leer la propiedad desde un objeto no definido

Si intentas acceder a una propiedad o leerla desde un objeto no definido, recibirás este error. Por ejemplo, este error puede ocurrir cuando intentas acceder a datos de un objeto en un arreglo, pero el objeto no está definido. Consulta la explicación detallada a continuación.

Cuerpo de la respuesta de error de ejemplo

{
    "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"
        }
    }
}

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen, el número de línea donde ocurrió el error y la descripción del error. Puedes encontrar esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en la siguiente faultstring, el nombre de la política es ParseJSONResponse, el archivo de origen es ParseJSONResponse.js, el número de línea es 6 y la descripción del error es 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)\""
    

    El error indica que longitud de la propiedad no se puede leer desde un objeto no definido.

  2. Examina el número de línea del archivo de origen de JavaScript (identificado en el paso n.º 1 anterior) y verifica si el objeto tiene un valor válido o no está definido. Es posible que tengas que leer y comprender el archivo de origen completo para determinar cómo se definió o derivó el objeto específico y determinar la razón por la que el objeto no está definido. Si descubres que el objeto específico no está definido e intentas acceder a la propiedad de longitud desde él, esa es la causa del error.

    Veamos un ejemplo para comprender mejor este problema:

    1. Supongamos que recibes la siguiente respuesta JSON desde el servidor de backend:

      {
          "cars": [
             { "name":"Toyota", "count": 150 }
             { "name":"Honda", "count": 100 },
             { "name":"Ford", "count": 75 }
          ]
      }
      
    2. A continuación, mostramos un ejemplo de archivo de origen de JavaScript que analiza esta respuesta JSON y genera el error antes mencionado:

      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. Cuando examinas el código de JavaScript con cuidado, puedes ver que, en la línea número 2, response.content se lee/almacena en la variable jsonData como una string regular (entre comillas).

    4. Dado que jsonData es una string regular, cuando intentes acceder a cars desde jsonData (jsonData.cars) no estará definido.

    5. Posteriormente, cuando intentes leer la propiedad length desde jsonData.cars, que no está definida, obtendrás el siguiente error:

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

Solución

Asegúrate de leer siempre datos JSON como un objeto JSON con las API de JSON pertinentes.

A fin de corregir el ejemplo de JavaScript descrito anteriormente, puedes usar la función JSON.parse() en el objeto response.content para obtenerlo como un objeto JSON. Después de esto, puedes acceder al arreglo cars e iterar el arreglo correctamente.

// 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);
}

Error de URI

El tipo de error URIError se muestra si usas caracteres no válidos en una función de URI. Por ejemplo, si pasas un URI que tiene un símbolo de porcentaje a las funciones decodeURI o decodeURIComponent, recibirás este error.

Cuerpo de la respuesta de error

{
    "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"
        }
    }
}

Cuerpo de la respuesta de error de ejemplo

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

Diagnóstico

  1. Identifica la política de JavaScript, su archivo de origen, el número de línea donde ocurrió el error y la descripción del error. Puedes encontrar toda esta información en el elemento de la string del error de la respuesta de error. Por ejemplo, en la siguiente string con errores, el nombre de la política de JavaScript es URIDecode</code, el archivo de origen de JavaScript es URIDecode.js, el número de línea es 2 y la descripción del error es Malformed URI sequence:

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

    La descripción del error indica que se usó una secuencia de URI con formato incorrecto en la línea número 2 de URIDecode.js.

  2. Examina el archivo fuente de JavaScript y verifica si el argumento que se pasó a alguna de las funciones del URI contiene caracteres no válidos. De ser así, esa es la causa del error.

    A continuación, te mostramos un ejemplo de archivo de origen de JavaScript que genera este error:

    URIDecode.js

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

    En el código de JavaScript de ejemplo anterior, la variable str que se pasó a decodeURIComponent() tiene un símbolo de porcentaje, que se considera un carácter no válido. Por lo tanto, verás el siguiente error:

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

Solución

Asegúrese de que todos los caracteres utilizados en las funciones de URI sean válidos y estén permitidos.

Para corregir el problema con el ejemplo de JavaScript descrito anteriormente, codifica el símbolo de porcentaje. Por ejemplo, %25:

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