Solução de problemas de erro de ambiente de execução de política do JavaScript

Esta é a documentação da Apigee e da Apigee híbrida.
Confira a documentação da Apigee Edge.

ScriptExecutionFailed

Código do 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 do JavaScript pode gerar muitos tipos diferentes de erros ScriptExecutionFailed. Alguns dos erros mais comuns estão listados na tabela abaixo:

Tipo de erro Causa
Erro de intervalo Um RangeError é gerado quando você usa um número que está fora do intervalo de valores válidos.
Erro de referência Um ReferenceError será gerado se você usar (mencionar) uma variável que não foi declarada.
Erro de sintaxe Um SyntaxError será gerado se você tentar avaliar o código com um erro de sintaxe.
Erro de tipo Um TypeError será gerado se você usar uma operação que esteja fora do intervalo de tipos esperados.
Erro de URI Um URIError será gerado se você usar caracteres inválidos em uma função de URI.

Erro de intervalo

O tipo de erro RangeError é gerado quando você opera em um valor ou transmite um valor para uma função que não está no conjunto ou intervalo de valores permitidos.

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

  1. Se você usar uma data inválida, como 31 de setembro de 2018, com algumas das APIs Date.
  2. Se você transmitir um valor inválido para métodos numéricos, como Number.toPrecision(), Number.tofixed() ou Number.toExponential(). Por exemplo, digamos que você transmita um valor alto, como 400 ou 500, no método Number.toPrecision(), verá um erro de intervalo.
  3. Se você criar uma matriz com comprimento inválido.

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

Observação: o diagnóstico e a resolução de erros de intervalo dependem da mensagem de erro exata gerada pela política do JavaScript. Veja a seguir alguns exemplos.

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 do JavaScript, o arquivo de origem, o número da linha em que o erro ocorreu e a descrição do erro. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política do JavaScript é ParseDate, o arquivo de origem do JavaScript é ParseDate.js, o número da linha em que o erro ocorreu é 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 arquivo de origem do JavaScript (identificado na etapa 1 acima) e verifique se há uma data inválida usada no número da linha especificada no erro ou se a variável usada no número da linha tem uma data inválida. Se uma data inválida foi usada, essa é a causa do erro.

    Veja um exemplo de arquivo de origem do JavaScript que leva a esse erro:

    ParseDate.js

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

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

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

Resolução

Sempre use uma data válida com as APIs Date no código do JavaScript.

Para corrigir o código do JavaScript de exemplo acima, defina 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 para APIs Precision

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 do JavaScript, o arquivo de origem, o número da linha em que o erro ocorreu e a descrição do erro. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política do JavaScript é SetNumberPrecision, o arquivo de origem do JavaScript é SetNumberPrecision.js, o número da linha em que o erro ocorreu é 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 arquivo de origem do JavaScript (identificado na etapa 1 acima). Se o número alto mencionado como parte da descrição do erro foi usado no número da linha específico, essa é a causa do erro.

    Veja um exemplo de arquivo de origem do JavaScript que leva a esse erro:

    SetNumberPrecision.js

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

    Neste exemplo, observe que um valor alto de 400 foi usado na linha número 2. Como não é possível definir a precisão como um número com tantos dígitos, você recebe este erro:

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

Resolução

Verifique se 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 relevantes 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 é gerado quando uma variável indefinida no 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 do JavaScript, o arquivo de origem e o número da linha em que a variável indefinida foi referenciada. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no faultstring a seguir, o nome da política do JavaScript é ComputeTotalPrice, o arquivo de origem correspondente é ComputeTotalPrice.js, o número da linha em que o erro ocorreu é 3 e o nome da variável indefinida é 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 arquivo de origem do JavaScript e verifique se a variável indefinida identificada na etapa 1 acima está sendo referenciada. Por exemplo, o código do JavaScript a seguir faz referência à variável indefinida price na linha 3, que corresponde ao que está na string com falha:

    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 do JavaScript. Se a variável não estiver definida, essa será a causa do erro.

    No exemplo de script mostrado acima, a variável price não declarada/definida foi usada. Portanto, você vê o seguinte erro:

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

Resolução

Verifique se todas as variáveis referenciadas no código do JavaScript estão definidas corretamente.

Para corrigir o problema com o JavaScript de exemplo mostrado acima, defina o preço da variável antes de usá-lo. 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 é gerado quando o mecanismo do JavaScript encontra tokens ou a ordem dos token não está em conformidade com a sintaxe da linguagem, ou quando uma entrada de formato inválida é passada para as APIs do analisador, como análise JSON/XML.

Por exemplo, se o payload JSON inválido ou malformado for transmitido como entrada para a API JSON.parse usada na política do JavaScript, você receberá esse 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 do JavaScript, o arquivo de origem, o número da linha em que o erro ocorreu e a descrição do erro. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política do JavaScript é ParseJSONRequest, o arquivo de origem do JavaScript é ParseJSONRequest.js, o número da linha em que o erro ocorreu é 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 arquivo de origem do JavaScript (identificado na etapa 1 acima) e verifique qual operação está sendo realizada. Se uma função JSON.parse() estiver sendo executada, verifique o parâmetro de entrada passado a ela. Se o parâmetro de entrada não for válido ou for JSON malformado, essa será a causa do erro.

    Este é um exemplo de código do JavaScript que causa esse erro:

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

    Neste exemplo, o payload de solicitação (request.content) transmitido para a API Proxy é usado como entrada para a função JSON.parse().

    Veja o exemplo de uma chamada de API que mostra como a solicitação foi passada:

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

    Na solicitação acima, o seguinte payload XML é transmitido para a API Proxy <city>Bangalore</city>. A API JSON.parse espera que um JSON válido seja transmitido, mas como um payload XML é transmitido, ela 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 passar uma entrada válida para as APIs de análise usadas no código do JavaScript.

Para corrigir o problema com a política de amostra discutida acima, transmita uma solicitação de payload JSON válida da seguinte maneira:

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 é gerado quando:

  • um operando ou argumento transmitido a uma função é incompatível com o tipo esperado por esse operador ou função;
  • uma função é invocada em um objeto nulo, indefinido ou errado;
  • uma propriedade é acessada de um objeto nulo, indefinido ou errado.

Por exemplo, um erro de tipo é gerado:

  • se você tentar invocar a função toUpperCase() em um número. Isso ocorre porque a função toUpperCase() pode ser invocada apenas em objetos de string;
  • Se você 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 você tentar invocar uma função em um objeto não compatível, receberá esse erro. Por exemplo, se você tentar invocar a função toUpperCase() em um número, receberá o erro. Isso ocorre porque a função toUpperCase() pode ser invocada apenas 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 do JavaScript, o arquivo de origem, o número da linha em que o erro ocorreu e a descrição do erro. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política do JavaScript é ConvertToUpperCase, o arquivo 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 você está invocando a função toUpperCase() em um objeto cujo valor numérico é 100.

  2. Examine o arquivo de origem do JavaScript e verifique se você está invocando a função toUpperCase() em um objeto cujo valor numérico seja 100 na linha número 2 (identificada na etapa 1 acima). Em caso afirmativo, essa é a causa do erro.

    Veja um exemplo de arquivo de origem do JavaScript que leva a esse erro:

    ConvertToUpperCase.js

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

    No código do JavaScript mostrado acima, a variável number foi definida com um valor de 100. Na sequência, a função toUpperCase()( foi invocada no objeto numérico. Como a função toUpperCase() pode ser invocada apenas em objetos de string, você 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

Sempre use funções como toUpperCase() em objetos válidos.

Para corrigir o exemplo mostrado acima, crie uma variável de string e invoque a função toUpperCase() em uma string:

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

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

Se você tentar acessar/ler uma propriedade de um objeto indefinido, esse erro será exibido. Por exemplo, este erro pode ocorrer quando você tenta acessar dados de um objeto em uma matriz, mas o objeto é indefinido. 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 do JavaScript, o arquivo de origem, o número da linha em que o erro ocorreu e a descrição do erro. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política é ParseJSONResponse, o arquivo 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 a propriedade length não pode ser lida de um objeto indefinido.

  2. Examine o número da linha no arquivo de origem do JavaScript (identificado na etapa 1 acima) e verifique se o objeto tem um valor válido ou não foi definido. Talvez seja necessário ler e entender o arquivo de origem completo para determinar como o objeto específico foi definido ou derivado e determinar por que o objeto ficou indefinido. Se você descobrir que o objeto específico está realmente indefinido e estiver tentando acessar o comprimento da propriedade dele, essa será a causa do erro.

    Veja um exemplo para entender melhor esse problema:

    1. Suponha que você receba a seguinte resposta JSON do servidor de back-end:

      {
          "cars": [
             { "name":"Toyota", "count": 150 }
             { "name":"Honda", "count": 100 },
             { "name":"Ford", "count": 75 }
          ]
      }
      
    2. Aqui está um exemplo de arquivo de origem do JavaScript que analisa a 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. Ao examinar o código do JavaScript com cuidado, você verá que o código response.content é lido/armazenado na variável jsonData como uma string regular (entre aspas) na linha número 2.

    4. Como jsonData é uma string regular, quando você tentar acessar cars de jsonData (jsonData.cars), ele será indefinido.

    5. Em seguida, quando você tentar ler a propriedade length de jsonData.cars, que é indefinida, receberá o erro:

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

Resolução

Sempre leia os dados JSON como um objeto JSON usando as APIs JSON relevantes.

Para corrigir o JavaScript de exemplo descrito acima, use a função JSON.parse() no objeto response.content para acessá-lo como um objeto JSON. Depois disso, você poderá acessar a matriz cars e fazer a iteração por meio dela.

// 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 será gerado se você usar caracteres inválidos em uma função de URI. Por exemplo, se você transmitir um URI com um símbolo de porcentagem para as funções decodeURI ou decodeURIComponent, receberá esse 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 do JavaScript, o arquivo de origem, o número da linha em que o erro ocorreu e a descrição do erro. Você encontra todas essas informações no elemento faultstring da resposta de erro. Por exemplo, no seguinte faultstring, o nome da política do JavaScript é URIDecode</code, o arquivo de origem do 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 uma sequência de URIs malformados foi usada na linha número 2 de URIDecode.js.

  2. Examine o arquivo de origem do JavaScript e verifique se o argumento passado a qualquer uma das funções de URI contém caracteres inválidos. Em caso afirmativo, essa é a causa do erro.

    Veja um exemplo de arquivo de origem do JavaScript que leva a esse erro:

    URIDecode.js

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

    No exemplo de código do JavaScript mostrado acima, a variável str passada para decodeURIComponent() tem um símbolo de porcentagem, que é considerado um caractere inválido. Portanto, você receberá o 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 caracteres usados nas funções de URI sejam válidos e permitidos.

Para corrigir o problema com o exemplo de JavaScript descrito acima, use a codificação do símbolo de porcentagem. Por exemplo, %25:

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