排解 JavaScript 政策執行階段錯誤

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

ScriptExecutionFailed

錯誤代碼

steps.javascript.ScriptExecutionFailed

錯誤回應主體

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

錯誤類型和可能原因

JavaScript 政策可能會擲回多種不同類型的 ScriptExecutionFailed 錯誤。 下表列出一些常見錯誤:

錯誤類型 原因
範圍錯誤 如果您使用的數字超出法律值的範圍,系統會擲回 RangeError
參考檔案錯誤 如果您使用 (參照) 未宣告的變數,系統會擲回 ReferenceError
語法錯誤 如果您嘗試評估含有語法錯誤的程式碼,則系統會擲回 SyntaxError
類型錯誤 如果您使用的作業超出預期類型範圍,則系統會擲回 TypeError
URI 錯誤 如果在 URI 函式中使用無效字元,系統會擲回 URIError

範圍錯誤

當您對值執行作業,或將值傳遞至不在允許值集或範圍內的函式時,系統會擲回 RangeError 錯誤類型。

例如,系統會在下列情況下擲回這項錯誤:

  1. 如果將部分 Date API 使用無效日期 (例如 2018 年 9 月 31 日)。
  2. 如果將無效的值傳遞至數字方法,例如 Number.toPrecision()Number.tofixed()Number.toExponential(),舉例來說,假設您在 Number.toPrecision() 方法中傳遞 400 或 500 等較大的值,就會看到範圍錯誤。
  3. 您建立長度無效的陣列。

錯誤回應主體

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

注意:範圍錯誤的診斷及解決方式取決於 JavaScript 政策擲回的確切錯誤訊息。以下提供一些範例供您參考。

範例 1:日期無效

錯誤回應主體範例

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

診斷

  1. 指明 JavaScript 政策、相關來源檔案、發生錯誤的行號和錯誤說明。您可以在錯誤回應的 faultstring 元素中找到所有這些資訊。例如,在下列 faultstring 中,JavaScript 政策名稱為 ParseDate,JavaScript 來源檔案為 ParseDate.js,發生錯誤的行數為 2,錯誤說明則為 Date is invalid

    "faultstring": "Execution of ParseDate failed with error: Javascript runtime error: \"RangeError: Date is invalid. (ParseDate.js:2)\""
    
  2. 檢查 JavaScript 來源檔案 (識別於上方步驟 1 所示),並檢查錯誤中指定的行數是否包含無效的日期,或行數中使用的變數是否含有無效的日期。如果使用的日期無效,就是發生錯誤的原因。

    以下提供引發這個錯誤的 JavaScript 來源檔案範例:

    ParseDate.js

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

    在這個範例中,第 2 行中有一個變數 date。檢查來源檔案時,您可以看到 date 變數設定的日期無效:2018-09-31T11:19:08.402Z. 這個日期無效,因為 9 月沒有 31 天。

    注意:本範例使用的 ISO-8601 格式是:YYYY-MM-DDTHH:mm:ss.sssZ

解析度

請務必在 JavaScript 程式碼中使用 Date API 時一律使用有效的日期。

如要修正上述 JavaScript 程式碼範例,您可以將日期設為 Sept 30 2018,如下所示:

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

示例 2:傳遞至精確度 API 的無效號碼

錯誤回應主體範例

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

診斷

  1. 指明 JavaScript 政策、相關來源檔案、發生錯誤的行號和錯誤說明。您可以在錯誤回應的 faultstring 元素中找到所有這些資訊。例如,在下列 faultstring 中,JavaScript 政策名稱為 SetNumberPrecision,JavaScript 來源檔案為 SetNumberPrecision.js,發生錯誤的行數為 2,錯誤說明則為 Precision 400 out of range.

    "faultstring": "Execution of SetNumberPrecision failed with error: Javascript runtime error: "RangeError: Precision 400 out of range. (SetNumberPrecision.js:2)\""
    
  2. 檢查 JavaScript 來源檔案 (識別在上述步驟 1 中)。如果錯誤說明中提及的大數字用在特定的行數,這就是錯誤原因。

    以下提供引發這個錯誤的 JavaScript 來源檔案範例:

    SetNumberPrecision.js

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

    在這個範例中,請注意第 2 行使用了較大的 400 值。由於無法將精確度設為這麼多位數,因此系統會顯示下列錯誤:

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

解析度

確認 toPrecision() 方法中使用的數字位於允許的值集中。

如要修正上述 JavaScript 範例的問題,請將有效數字位數設為 2 代表有效數字:

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

參照錯誤

使用 (參照) 或操作 JavaScript 中未定義變數時,系統會擲回錯誤類型 ReferenceError

錯誤回應主體

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

錯誤回應主體範例

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

診斷

  1. 找出 JavaScript 政策、其來源檔案,以及參照未定義變數的行數。您可以在錯誤回應的 faultstring 元素中找到所有這些資訊。舉例來說,下列 faultstring 的 JavaScript 政策名稱為 ComputeTotalPrice,對應的來源檔案為 ComputeTotalPrice.js,發生錯誤的行數為 3,未定義的變數名稱為 price.

    "faultstring": "Execution of ComputeTotalPrice failed with error: Javascript runtime error: \"ReferenceError: \"price\" is not defined. (ComputeTotalPrice.js:3)\""
    
  2. 檢查 JavaScript 來源檔案中的行號,確認系統是否參照上述步驟 1 中指明的未定義的變數。舉例來說,下列 JavaScript 程式碼參照第 3 行中未定義變數的 price,該變數與錯字串中的內容相符:

    ComputeTotalPrice.js

    var item = context.getVariable("request.queryparam.item");
    var quantity = context.getVariable("request.queryparam.quantity");
    var totalprice = parseInt(quantity) * parseInt(price);
    context.setVariable("TotalPrice", totalprice);
    
    
  3. 檢查 JavaScript 程式碼中是否已定義特定變數。如果沒有定義變數,則表示發生錯誤。

    在上述範例指令碼中,系統會使用未宣告/定義的 price 變數;因此,您會看到以下錯誤:

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

解析度

確保 JavaScript 程式碼中參照的所有變數皆已正確定義。

如要修正上述 JavaScript 範例的問題,請先定義變數價格,再使用該變數。例如:

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

語法錯誤

當 JavaScript 引擎遇到與語言語法不符的權杖或權杖順序,或是將無效的格式輸入內容傳遞至剖析器 API (例如 JSON/XML 剖析) 時,就會擲回 SyntaxError 錯誤類型。

舉例來說,如果以輸入內容的形式傳遞無效或格式錯誤的 JSON 酬載做為 JavaScript 政策中使用的 JSON.parse API,就會顯示這個錯誤。

錯誤回應主體

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

錯誤回應主體範例

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

診斷

  1. 指明 JavaScript 政策、相關來源檔案、發生錯誤的行號和錯誤說明。您可以在錯誤回應的 faultstring 元素中找到所有這些資訊。例如,在下列 faultstring 中,JavaScript 政策名稱為 ParseJSONRequest,JavaScript 來源檔案為 ParseJSONRequest.js,發生錯誤的行數為 2,錯誤說明則為 Unexpected token

    "faultstring": "Execution of ParseJSONRequest failed with error: Javascript runtime error: \"SyntaxError: Unexpected token: <. (ParseJSONRequest.js:2)\""
    
  2. 檢查 JavaScript 來源檔案中的行 2 (如上方步驟 1 所示),並檢查正在執行的作業。如果正在執行 JSON.parse() 函式,請檢查傳遞給函式的輸入參數。如果輸入參數無效或 JSON 格式錯誤,就是發生錯誤的原因。

    以下提供引發這個錯誤的 JavaScript 程式碼範例:

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

    在這個範例中,傳送至 API Proxy 的要求酬載 (request.content) 會做為 JSON.parse() 函式的輸入內容。

    以下是 API 呼叫範例,顯示如何傳送要求:

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

    在上述要求中,下列 XML 酬載會傳遞至 API Proxy <city>Bangalore</city>JSON.parse API 預期系統會傳遞有效的 JSON,但因為改為傳遞 XML 酬載,導致失敗,並出現以下錯誤:

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

解析度

請務必將有效的輸入內容傳遞給 JavaScript 程式碼中使用的剖析 API。

如要修正上述範例政策的問題,請傳送有效的 JSON 酬載要求,如下所示:

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

類型錯誤

發生下列情況時,系統會擲回 TypeError 錯誤類型:

  • 傳送至函式的運算元或引數與該運算子或函式預期的類型不相容。
  • 系統針對空值、未定義或錯誤的物件叫用函式。
  • 從空值、未定義或錯誤的物件存取屬性。

例如,系統會擲回類型錯誤:

  • 如果您嘗試對數字叫用 toUpperCase() 函式,這是因為您只能針對字串物件叫用 toUpperCase() 函式。
  • 如果您嘗試讀取空值或未定義物件的屬性。

錯誤回應主體

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

範例 1:在錯誤的物件上叫用函式

如果您嘗試對不支援的物件叫用函式,就會收到這則錯誤訊息。例如,如果您嘗試對某個數字叫用 toUpperCase() 函式,就會收到錯誤訊息。這是因為您只能針對字串物件叫用 toUpperCase() 函式。

錯誤回應主體範例

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

診斷

  1. 指明 JavaScript 政策、相關來源檔案、發生錯誤的行號和錯誤說明。您可以在錯誤回應的 faultstring 元素中找到所有這些資訊。舉例來說,下列 faultstring 的 JavaScript 政策名稱為 ConvertToUpperCase,來源檔案為 ConvertToUpperCase.js,行數是 2,錯誤說明則為 **Cannot find function toUpperCase in object 100.

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

    錯誤說明表示您針對數值為 100 的物件叫用函式 toUpperCase()

  2. 檢查 JavaScript 來源檔案,並驗證您是否針對第 2 行數字值為 100 的物件叫用函式 toUpperCase() (請見上述步驟 # 1 的說明)。如果是的話,這就是錯誤的原因。

    以下提供引發這個錯誤的 JavaScript 來源檔案範例:

    ConvertToUpperCase.js

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

    在上述 JavaScript 程式碼中,變數 number 的值設為 100。接著,系統會在數字物件上叫用 toUpperCase()( 函式。由於您只能在字串物件上叫用 toUpperCase() 函式,因此會收到以下錯誤訊息:

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

解析度

一律在有效物件中使用 toUpperCase() 等函式。

如要修正上方範例,您可以建立字串變數,然後在字串上叫用 toUpperCase() 函式:

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

範例 2:無法讀取未定義物件的屬性

如果您嘗試從未定義的物件存取/讀取屬性,就會收到這個錯誤。例如,嘗試存取陣列中的物件資料,但物件未定義時,就會發生這個錯誤。請參閱下方的詳細說明。

錯誤回應主體範例

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

診斷

  1. 指明 JavaScript 政策、相關來源檔案、發生錯誤的行號和錯誤說明。您可以在錯誤回應的 faultstring 元素中找到所有這些資訊。例如,下列 faultstring 的政策名稱為 ParseJSONResponse、來源檔案為 ParseJSONResponse.js,行號為 6,錯誤說明則為 Cannot read property "length" from undefined

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

    錯誤表示無法從未定義的物件讀取 length 屬性。

  2. 檢查 JavaScript 來源檔案中的行數 (如上方步驟 1 所示),並確認物件含有有效值或未定義。您可能需要閱讀並瞭解完整的來源檔案,才能判斷特定物件的定義或衍生方式,以及判斷物件未定義的原因。如果您發現特定物件確實未定義,並且嘗試從該物件存取屬性長度,就就是造成錯誤的原因。

    讓我們透過範例進一步瞭解這個問題:

    1. 假設您從後端伺服器收到下列 JSON 回應:

      {
          "cars": [
             { "name":"Toyota", "count": 150 }
             { "name":"Honda", "count": 100 },
             { "name":"Ford", "count": 75 }
          ]
      }
      
    2. 以下是剖析此 JSON 回應並促成上述錯誤的範例 JavaScript 來源檔案:

      ParseJSONResponse.js

      // Get the JSON response
      var jsonData = context.getVariable("response.content");
      print (jsonData);
      
      // Read the cars array
      for (var i = 0; i < jsonData.cars.length; i++)
        {
        print("name = " + jsonData.cars[i].name);
        print("count = " + jsonData.cars[i].count);
        }
      
    3. 仔細檢查 JavaScript 程式碼後,您會發現第 2 行會將 response.content 讀取/儲存至變數 jsonData,做為一般字串 (在引號中)。

    4. 由於 jsonData 是一般字串,因此您在從 jsonData (jsonData.cars) 存取 cars 時,不會定義。

    5. 後續嘗試從 jsonData.cars 讀取屬性 length (未定義) 時,您會收到錯誤訊息:

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

解析度

確保一律使用相關 JSON API 將 JSON 資料讀取為 JSON 物件。

如要修正上述 JavaScript 範例,您可以在 response.content 物件上使用 JSON.parse() 函式,取得其 JSON 物件。啟用後,您可以存取 cars 陣列並成功疊代整個陣列。

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

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

URI 錯誤

如果在 URI 函式中使用無效字元,系統會擲回 URIError 錯誤類型。舉例來說,如果您將含百分比符號的 URI 傳遞至 decodeURIdecodeURIComponent 函式,就會發生這個錯誤。

錯誤回應主體

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

錯誤回應主體範例

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

診斷

  1. 找出 JavaScript 政策、相關來源檔案、發生錯誤的行號和錯誤說明。您可以在錯誤回應的 errorstring 元素中找到所有這些資訊。舉例來說,在下列錯誤字串中,JavaScript 政策名稱為 URIDecode</code,JavaScript 來源檔案為 URIDecode.js,行數為 2,錯誤說明則為 Malformed URI sequence

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

    錯誤說明指出 URIDecode.js 的第 2 行使用了格式錯誤的 URI 序列。

  2. 檢查 JavaScript 來源檔案,確認傳遞至任何 URI 函式的引數是否包含任何無效字元。如果是的話,這就是錯誤的原因。

    以下的 JavaScript 來源檔案範例會引發這個錯誤:

    URIDecode.js

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

    在上方顯示的 JavaScript 程式碼範例中,傳遞至 decodeURIComponent() 的變數 str 包含百分比符號,此符號會被視為無效字元,因此您會收到錯誤訊息:

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

解析度

確保 URI 函式中使用的所有字元均符合法律規範。

如要修正上述 JavaScript 範例的問題,請將百分比符號編碼。例如 %25

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