Solucionar problemas de errores del entorno de ejecución de políticas de JavaScript

Estás consultando 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 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 generar muchos tipos distintos de errores ScriptExecutionFailed. En la tabla siguiente se indican algunos de los errores más habituales:

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

Error de intervalo

El tipo de error RangeError se produce cuando se opera con un valor o se pasa un valor a una función que no está en el conjunto o intervalo de valores permitidos.

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

  1. Si usas una fecha no válida, como el 31 de septiembre del 2018, con algunas de las APIs de Date.
  2. Si envías un valor no válido a métodos numéricos, como Number.toPrecision(), Number.tofixed() o Number.toExponential(). Por ejemplo, si pasa un valor grande, como 400 o 500, en el método Number.toPrecision(), se producirá un error de intervalo.
  3. Si creas una matriz con una longitud no válida.

Cuerpo de 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 intervalo dependen del mensaje de error exacto que genere la política de JavaScript. A continuación, se describen un par de ejemplos para que te sirvan de referencia.

Ejemplo 1: Fecha no válida

Cuerpo de 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 en el que se ha producido el error y la descripción del error. Puede encontrar toda 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 ParseDate, el archivo de origen de JavaScript es ParseDate.js, el número de línea en el que se ha producido 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 de origen de JavaScript (identificado en el paso 1 anterior) y comprueba si se está usando una fecha no válida en el número de línea especificado en el error o si la variable usada en el número de línea tiene una fecha no válida. Si se usa una fecha no válida, esa será la causa del error.

    A continuación, se muestra un ejemplo de archivo de origen de JavaScript que provoca este error:

    ParseDate.js

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

    En este ejemplo, hay una variable date que se usa en la línea 2. Si examinas el archivo de origen, verás que la variable date se ha definido 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.

Resolución

Asegúrate de usar siempre una fecha válida al usar las APIs de Date en el código JavaScript.

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

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

Ejemplo 2: Número no válido enviado a las APIs de precisión

Cuerpo de 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. Identifique la política de JavaScript, su archivo de origen, el número de línea en el que se ha producido el error y la descripción del error. Puede encontrar toda 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 en el que se ha producido 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 de origen de JavaScript (identificado en el paso 1 anterior). Si el número grande que se menciona en la descripción del error se usa en el número de línea específico, esa es la causa del error.

    A continuación, se muestra un ejemplo de archivo de origen de JavaScript que provoca este error:

    SetNumberPrecision.js

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

    En este ejemplo, observa que se usa un valor grande (400) en la línea 2. Como no puedes definir la precisión con un número tan grande de dígitos, aparece el siguiente error:

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

Resolución

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

Para solucionar el problema con el ejemplo de JavaScript descrito anteriormente, asigna el número de dígitos significativos a 2, que es un valor 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 produce cuando se usa (se hace referencia a ella) o se opera con una variable indefinida en JavaScript.

Cuerpo de 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 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 en el que se hace referencia a la variable indefinida. Puede encontrar toda 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 fuente correspondiente es ComputeTotalPrice.js, el número de línea en el que se ha producido el error es 3 y el nombre de la variable indefinida 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 comprueba si se hace referencia a la variable indefinida identificada en el paso 1 anterior. Por ejemplo, el siguiente código JavaScript hace referencia a la variable indefinida price en la línea 3, que coincide con lo que hay en 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. Comprueba si la variable específica está definida en el código JavaScript. Si la variable no está definida, esa es la causa del error.

    En la secuencia de comandos de ejemplo que se muestra arriba, se usa la variable price, que no se ha declarado ni definido. 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)\""
    

Resolución

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

Para solucionar el problema con el ejemplo de JavaScript que se muestra arriba, define la variable price antes de usarla. 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);

Error de sintaxis

El tipo de error SyntaxError se produce cuando el motor de JavaScript detecta tokens o un orden de tokens que no se ajusta a la sintaxis del lenguaje, o cuando se pasa una entrada de formato no válida a las APIs del analizador, como el análisis de JSON o XML.

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

Cuerpo de 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 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. Identifique la política de JavaScript, su archivo de origen, el número de línea en el que se ha producido el error y la descripción del error. Puede encontrar toda 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 ParseJSONRequest, el archivo de origen de JavaScript es ParseJSONRequest.js, el número de línea en el que se ha producido 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. Examina la línea 2 del archivo de origen de JavaScript (identificado en el paso 1 anterior) y comprueba qué operación se está realizando. Si se está ejecutando una función JSON.parse(), comprueba el parámetro de entrada que se le ha pasado. Si el parámetro de entrada no es válido o el formato JSON es incorrecto, ese será el motivo del error.

    A continuación, se muestra un ejemplo de código JavaScript que provoca 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 se envía al proxy de la API se usa como entrada para la función JSON.parse().

    A continuación, se muestra una llamada de API de ejemplo que muestra cómo se ha enviado 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, la siguiente carga útil XML se transfiere al proxy de API <city>Bangalore</city>. La API JSON.parse espera que se le transfiera un archivo JSON válido, pero, como se le transfiere una carga útil XML, se produce el siguiente error:

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

Resolución

Asegúrate de enviar entradas válidas a las APIs de análisis utilizadas en el código JavaScript.

Para solucionar el problema con la política de muestra que hemos comentado, envía 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 se genera cuando:

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

Por ejemplo, se produce 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 cadena.
  • Si intentas leer una propiedad de un objeto nulo o indefinido.

Cuerpo de 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: Invocar una función en el objeto incorrecto

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

Cuerpo de 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. Identifique la política de JavaScript, su archivo de origen, el número de línea en el que se ha producido el error y la descripción del error. Puede encontrar toda 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 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 de origen de JavaScript y comprueba si estás invocando la función toUpperCase() en un objeto cuyo valor numérico es 100 en la línea 2 (identificada en el paso 1 anterior). Si es así, esa es la causa del error.

    A continuación, se muestra un ejemplo de archivo de origen de JavaScript que provoca este error:

    ConvertToUpperCase.js

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

    En el código JavaScript que se muestra arriba, la variable number tiene el valor 100. Después, se invoca la función toUpperCase()( en el objeto de número. Como la función toUpperCase() solo se puede invocar en objetos de cadena, se produce el siguiente error:

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

Resolución

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

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

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

Ejemplo 2: No se puede leer la propiedad de un objeto indefinido

Si intentas acceder o leer una propiedad de un objeto indefinido, se mostrará este error. Por ejemplo, este error puede producirse cuando intentas acceder a datos de un objeto de una matriz, pero el objeto no está definido. Consulta la explicación detallada que aparece más abajo.

Cuerpo de 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 en el que se ha producido el error y la descripción del error. Puede encontrar toda esta información en el elemento faultstring de la respuesta de error. Por ejemplo, en el 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 la propiedad length no se puede leer de un objeto indefinido.

  2. Examina el número de línea del archivo de origen de JavaScript (identificado en el paso 1 anterior) y comprueba 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 ha definido o derivado el objeto específico y por qué se considera indefinido. Si compruebas que el objeto específico no está definido y estás intentando acceder a la propiedad length, esa es la causa del error.

    Veamos un ejemplo para entender mejor este problema:

    1. Supongamos que recibes la siguiente respuesta JSON del servidor backend:

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

      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. Si examina detenidamente el código JavaScript, verá que, en la línea 2, response.content se lee o se almacena en la variable jsonData como una cadena normal (entre comillas).

    4. Como jsonData es una cadena normal, cuando intentes acceder a cars desde jsonData (jsonData.cars), el resultado será undefined.

    5. Después, cuando intentes leer la propiedad length de jsonData.cars, que no está definida, recibirás el siguiente error:

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

Resolución

Asegúrate de leer siempre los datos JSON como un objeto JSON mediante las APIs JSON pertinentes.

Para 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, podrás acceder al array cars e iterar en él 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 produce si usas caracteres no permitidos en una función URI. Por ejemplo, si pasas un URI que tiene un símbolo de porcentaje a las funciones decodeURI o decodeURIComponent, se producirá este error.

Cuerpo de 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 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 en el que se ha producido el error y la descripción del error. Puedes encontrar toda 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 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 ha usado una secuencia de URI incorrecta en la línea 2 de URIDecode.js.

  2. Examina el archivo de origen de JavaScript y comprueba si el argumento que se ha transferido a alguna de las funciones URI contiene caracteres no permitidos. Si es así, esa es la causa del error.

    A continuación, se muestra un ejemplo de archivo de origen de JavaScript que provoca este error:

    URIDecode.js

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

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

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

Resolución

Asegúrate de que todos los caracteres utilizados en las funciones de URI sean legales y estén permitidos.

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