Resolução de problemas de erros de tempo de execução da política de JavaScript

Está a ver a documentação do Apigee e do Apigee Hybrid.
Ver documentação do Apigee Edge.

ScriptExecutionFailed

Código de erro

steps.javascript.ScriptExecutionFailed

Corpo da resposta de erro

{
    "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 erros e possíveis causas

A política de JavaScript pode gerar muitos tipos diferentes de erros ScriptExecutionFailed. Alguns dos erros mais comuns são apresentados na tabela abaixo:

Tipo de erro Causa
Erro de intervalo É gerado um RangeError se usar um número que esteja fora do intervalo de valores legais.
Erro de referência É gerado um ReferenceError se usar (fizer referência a) uma variável que não tenha sido declarada.
Erro de sintaxe É gerado um SyntaxError se tentar avaliar código com um erro de sintaxe.
Erro de tipo É gerado um TypeError se usar uma operação que esteja fora do intervalo de tipos esperados.
Erro de URI É gerado um URIError se usar carateres ilegais numa função URI.

Erro de intervalo

O tipo de erro RangeError é lançado quando opera num valor ou passa um valor para uma função que não está no conjunto ou no intervalo de valores permitidos.

Por exemplo, este erro é apresentado nas seguintes circunstâncias:

  1. Se usar uma data inválida, como 31 de setembro de 2018, com algumas das APIs Date.
  2. Se transmitir um valor inválido a métodos numéricos, como Number.toPrecision(), Number.tofixed() ou Number.toExponential(). Por exemplo, se transmitir um valor elevado, como 400 ou 500, no método Number.toPrecision(), é apresentado um erro de intervalo.
  3. Se criar uma matriz com um comprimento ilegal.

Corpo da resposta de erro

{
    "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: o diagnóstico e a resolução de erros de intervalo dependem da mensagem de erro exata emitida pela política de JavaScript. Seguem-se alguns exemplos para sua referência.

Exemplo 1: data inválida

Exemplo de corpo da resposta de erro

{
    "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. Identifique a política de JavaScript, o respetivo ficheiro de origem, o número da linha onde ocorreu o erro e a descrição do erro. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política de JavaScript é ParseDate, o ficheiro de origem JavaScript é ParseDate.js, o número da linha em que ocorreu o erro é 2 e a descrição do erro é Date is invalid:

    "faultstring": "Execution of ParseDate failed with error: Javascript runtime error: \"RangeError: Date is invalid. (ParseDate.js:2)\""
    
  2. Examine o ficheiro de origem JavaScript (identificado no passo n.º 1 acima) e verifique se está a ser usada uma data inválida no número da linha especificado no erro ou se a variável usada no número da linha tem uma data inválida. Se for usada uma data inválida, essa é a causa do erro.

    Segue-se um exemplo de ficheiro de origem JavaScript que leva a este erro:

    ParseDate.js

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

    Neste exemplo, existe uma variável date usada na linha número 2. Ao examinar o ficheiro de origem, pode ver que a variável date está definida com uma data inválida: 2018-09-31T11:19:08.402Z. Esta data é inválida porque setembro não tem 31 dias.

    Nota: o formato ISO 8601 usado neste exemplo é: YYYY-MM-DDTHH:mm:ss.sssZ

Resolução

Certifique-se de que usa sempre uma data válida quando usa APIs Date no código JavaScript.

Para corrigir o exemplo de código JavaScript apresentado acima, pode definir a data como Sept 30 2018, conforme mostrado abaixo:

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

Exemplo 2: número inválido transmitido às APIs de precisão

Exemplo de corpo da resposta de erro

{
    "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 a política de JavaScript, o respetivo ficheiro de origem, o número da linha onde ocorreu o erro e a descrição do erro. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política de JavaScript é SetNumberPrecision, o ficheiro de origem JavaScript é SetNumberPrecision.js, o número da linha em que ocorreu o erro é 2 e a descrição do erro é 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. Examine o ficheiro de origem JavaScript (identificado no passo n.º 1 acima). Se o número elevado mencionado como parte da descrição do erro for usado no número da linha específico, essa é a causa do erro.

    Segue-se um exemplo de ficheiro de origem JavaScript que leva a este erro:

    SetNumberPrecision.js

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

    Neste exemplo, repare que é usado um valor elevado de 400 na linha número 2. Uma vez que não pode definir a precisão para um número tão grande de dígitos, recebe o erro abaixo:

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

Resolução

Certifique-se de que o número usado no método toPrecision() está dentro do conjunto de valores permitidos.

Para corrigir o problema com o exemplo de JavaScript descrito acima, defina o número de dígitos significativos como 2, que é válido:

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

Erro de referência

O tipo de erro ReferenceError é lançado quando uma variável indefinida no seu JavaScript é usada (referenciada) ou operada.

Corpo da resposta de erro

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

Exemplo de corpo da resposta de erro

{
    "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. Identifique a política JavaScript, o respetivo ficheiro de origem e o número da linha onde a variável indefinida é referenciada. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política de JavaScript é ComputeTotalPrice, o ficheiro de origem correspondente é ComputeTotalPrice.js, o número da linha em que ocorreu o erro é 3 e o nome da variável não definida é price.

    "faultstring": "Execution of ComputeTotalPrice failed with error: Javascript runtime error: \"ReferenceError: \"price\" is not defined. (ComputeTotalPrice.js:3)\""
    
  2. Examine o número da linha no ficheiro de origem JavaScript e verifique se a variável indefinida identificada no passo n.º 1 acima está a ser referenciada. Por exemplo, o seguinte código JavaScript faz referência à variável indefinida price na linha 3, que corresponde ao que está em 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. Verifique se a variável específica está definida no código JavaScript. Se a variável não estiver definida, essa é a causa do erro.

    No script de exemplo apresentado acima, é usada a variável price não declarada/definida. Por conseguinte, é apresentado o erro abaixo:

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

Resolução

Certifique-se de que todas as variáveis referenciadas no código JavaScript estão corretamente definidas.

Para corrigir o problema com o exemplo de JavaScript apresentado acima, defina a variável price antes de a usar. Por exemplo:

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

Erro de sintaxe

O tipo de erro SyntaxError é lançado quando o motor JavaScript encontra tokens ou uma ordem de tokens que não está em conformidade com a sintaxe da linguagem, ou quando uma entrada de formato inválido é transmitida às APIs do analisador, como a análise JSON/XML.

Por exemplo, se o payload JSON inválido ou com formato incorreto for transmitido como entrada para a API JSON.parse usada na política JavaScript, recebe este erro.

Corpo da resposta de erro

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

Exemplo de corpo da resposta de erro

{
    "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 a política de JavaScript, o respetivo ficheiro de origem, o número da linha onde ocorreu o erro e a descrição do erro. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política de JavaScript é ParseJSONRequest, o ficheiro de origem JavaScript é ParseJSONRequest.js, o número da linha em que ocorreu o erro é 2 e a descrição do erro é Unexpected token:

    "faultstring": "Execution of ParseJSONRequest failed with error: Javascript runtime error: \"SyntaxError: Unexpected token: <. (ParseJSONRequest.js:2)\""
    
  2. Examine a linha número 2 no ficheiro de origem JavaScript (identificado no passo n.º 1 acima) e verifique que operação está a ser realizada. Se estiver a ser executada uma função JSON.parse(), verifique o parâmetro de entrada transmitido à mesma. Se o parâmetro de entrada não for válido ou for um JSON com formato incorreto, essa é a causa do erro.

    Segue-se um exemplo de código JavaScript que provoca este erro:

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

    Neste exemplo, a carga útil do pedido (request.content) transmitida ao proxy de API é usada como entrada para a função JSON.parse().

    Segue-se o exemplo de chamada da API que mostra como o pedido foi transmitido:

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

    No pedido acima, a seguinte carga útil XML é transmitida ao proxy da API <city>Bangalore</city>. A API JSON.parse espera que seja transmitido um JSON válido, mas, como é transmitido um payload XML, ocorre uma falha com o erro abaixo:

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

Resolução

Certifique-se de que transmite uma entrada válida às APIs de análise usadas no código JavaScript.

Para corrigir o problema com a política de exemplo abordada acima, transmita um pedido de payload JSON válido da seguinte forma:

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

Erro de tipo

O tipo de erro TypeError é acionado quando:

  • Um operando ou um argumento transmitido a uma função é incompatível com o tipo esperado por esse operador ou função.
  • Uma função é invocada num objeto nulo, indefinido ou incorreto.
  • É acedida uma propriedade a partir de um objeto nulo, indefinido ou incorreto.

Por exemplo, é acionado um erro de tipo:

  • Se tentar invocar a função toUpperCase() num número. Isto deve-se ao facto de a função toUpperCase() só poder ser invocada em objetos de string.
  • Se tentar ler uma propriedade de um objeto nulo ou indefinido.

Corpo da resposta de erro

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

Exemplo 1: invocar uma função no objeto errado

Se tentar invocar uma função num objeto não suportado, recebe este erro. Por exemplo, se tentar invocar a função toUpperCase() num número, recebe o erro. Isto acontece porque a função toUpperCase() só pode ser invocada em objetos de string.

Exemplo de corpo da resposta de erro

{
    "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 a política de JavaScript, o respetivo ficheiro de origem, o número da linha onde ocorreu o erro e a descrição do erro. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política de JavaScript é ConvertToUpperCase, o ficheiro de origem é ConvertToUpperCase.js, o número da linha é 2 e a descrição do erro é **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)\""
    

    A descrição do erro indica que está a invocar a função toUpperCase() num objeto cujo valor numérico é 100.

  2. Examine o ficheiro de origem JavaScript e verifique se está a invocar a função toUpperCase() num objeto cujo valor numérico é 100 na linha número 2 (identificado no passo n.º 1 acima). Se sim, essa é a causa do erro.

    Segue-se um exemplo de ficheiro de origem JavaScript que leva a este erro:

    ConvertToUpperCase.js

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

    No código JavaScript apresentado acima, a variável number está definida com um valor de 100. Posteriormente, a função toUpperCase()( é invocada no objeto number. Uma vez que a função toUpperCase() só pode ser invocada em objetos de string, recebe o erro:

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

Resolução

Use sempre funções como toUpperCase() em objetos válidos.

Para corrigir o exemplo apresentado acima, pode criar uma variável de string e, em seguida, invocar a função toUpperCase() numa string:

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

Exemplo 2: não é possível ler a propriedade de um objeto indefinido

Se tentar aceder/ler uma propriedade de um objeto indefinido, recebe este erro. Por exemplo, este erro pode ocorrer quando tenta aceder a dados de um objeto numa matriz, mas o objeto não está definido. Veja a explicação detalhada abaixo.

Exemplo de corpo da resposta de erro

{
    "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. Identifique a política de JavaScript, o respetivo ficheiro de origem, o número da linha onde ocorreu o erro e a descrição do erro. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política é ParseJSONResponse, o ficheiro de origem é ParseJSONResponse.js, o número da linha é 6 e a descrição do erro é 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)\""
    

    O erro indica que não é possível ler a propriedade length de um objeto indefinido.

  2. Examine o número da linha no ficheiro de origem JavaScript (identificado no passo n.º 1 acima) e verifique se o objeto tem um valor válido ou não está definido. Pode ter de ler e compreender o ficheiro de origem completo para determinar como o objeto específico foi definido ou derivado e determinar por que motivo o objeto é considerado indefinido. Se verificar que o objeto específico está realmente indefinido e estiver a tentar aceder à propriedade length a partir dele, essa é a causa do erro.

    Vejamos um exemplo para compreender melhor este problema:

    1. Suponha que recebe a seguinte resposta JSON do servidor de back-end:

      {
          "cars": [
             { "name":"Toyota", "count": 150 }
             { "name":"Honda", "count": 100 },
             { "name":"Ford", "count": 75 }
          ]
      }
      
    2. Segue-se um exemplo de um ficheiro de origem JavaScript que analisa esta resposta JSON e leva ao erro mencionado acima:

      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. Se examinar cuidadosamente o código JavaScript, pode ver que, na linha número 2, o response.contenté lido/armazenado na variável jsonData como uma string normal (entre aspas).

    4. Uma vez que jsonData é uma string normal, quando tenta aceder a cars a partir de jsonData (jsonData.cars) não está definido.

    5. Posteriormente, quando tenta ler a propriedade length de jsonData.cars, que não está definida, recebe o erro:

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

Resolução

Certifique-se de que lê sempre os dados JSON como um objeto JSON através das APIs JSON relevantes.

Para corrigir o exemplo de JavaScript descrito acima, pode usar a função JSON.parse() no objeto response.content para o obter como um objeto JSON. Depois disto, pode aceder à matriz cars e iterar com êxito na matriz.

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

Erro de URI

O tipo de erro URIError é lançado se usar carateres ilegais numa função URI. Por exemplo, se transmitir um URI que tenha um símbolo de percentagem às funções decodeURI ou decodeURIComponent, recebe este erro.

Corpo da resposta de erro

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

Exemplo de corpo da resposta de erro

{
    "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. Identifique a política de JavaScript, o respetivo ficheiro de origem, o número da linha onde ocorreu o erro e a descrição do erro. Pode encontrar todas estas informações no elemento faultstring da resposta de erro. Por exemplo, na seguinte faultstring, o nome da política de JavaScript é URIDecode</code, o ficheiro de origem de JavaScript é URIDecode.js, o número da linha é 2 e a descrição do erro é Malformed URI sequence:

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

    A descrição do erro indica que é usada uma sequência de URI com formato incorreto na linha 2 de URIDecode.js.

  2. Examine o ficheiro de origem JavaScript e verifique se o argumento transmitido a qualquer uma das funções URI contém carateres ilegais. Se sim, essa é a causa do erro.

    Segue-se um exemplo de um ficheiro de origem JavaScript que gera este erro:

    URIDecode.js

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

    No exemplo de código JavaScript apresentado acima, a variável str transmitida a decodeURIComponent() tem um símbolo de percentagem, que é considerado um caráter ilegal. Por conseguinte, recebe o seguinte erro:

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

Resolução

Certifique-se de que todos os carateres usados nas funções de URI são legais e permitidos.

Para corrigir o problema com o exemplo de JavaScript descrito acima, codifique o símbolo de percentagem. Por exemplo, %25:

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