ServiceCallout 运行时错误问题排查

您正在查看 ApigeeApigee Hybrid 文档。
查看 Apigee Edge 文档。

RequestVariableNotMessageType

错误代码

steps.servicecallout.RequestVariableNotMessageType

错误响应正文

{
    "fault": {
        "faultstring": "ServiceCallout[POLICY_NAME]: request variable [VARIABLE_NAME] value is not of type Message",
        "detail": {
            "errorcode": "steps.servicecallout.RequestVariableNotMessageType"
        }
    }
}

原因

如果 ServiceCallout 策略<Request> 元素中指定的变量不是 message 类型,则会出现此错误。如果变量是字符串或任何其他非消息类型,您将会看到此错误。

消息类型变量表示整个 HTTP 请求和响应。内置流变量 requestresponsemessage 都属于 message 类型。

诊断

  1. 指出发生错误的 ServiceCallout 政策以及类型错误的变量名称。您可以在错误响应的 faultstring 元素中找到这两项。例如,在以下 faultstring 中,政策名称为 ExecuteGeocodingRequest,变量为 PostalCode

    "faultstring": "ServiceCallout[ExecuteGeocodingRequest]: request variable PostalCode value is not of type Message"

  2. 在失败的 ServiceCallout 政策 XML 中,验证 <Request> 元素中的变量名称是否与故障字符串中标识的变量名称(上方第 1 步中)一致。例如,以下政策指定了名为 PostalCode 的请求变量,该变量与 faultstring 中的相应内容一致:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ServiceCallout name="ExecuteGeocodingRequest">
        <Request variable="PostalCode"/>
        <Response>GeocodingResponse</Response>
        <HTTPTargetConnection>
            <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
        </HTTPTargetConnection>
    </ServiceCallout>
    
  3. 确定此变量是否为消息类型:

    1. 在首次定义变量的 API 代理软件包中找到代码。
    2. 在大多数情况下,您会在另一个先于 ServiceCallout 政策执行的政策中发现问题变量已被创建并填充。例如,分配消息政策通常用于在 API 代理流程中创建和填充变量。
    3. 确定首次在其中定义并填充变量的政策后,您需要按以下方式确定该变量的类型:
      • 检查 type 属性的值(如果存在)。
      • 如果 type 属性不存在,则该变量将被视为字符串。
    4. 如果变量的类型是非消息(例如字符串),则会导致错误。如需了解常见变量及其类型,请参阅流变量参考文档

例如,假设 ServiceCallout 政策中引用的 PostalCode 变量是在以下所示的 AssignMessage 政策中创建的。请注意,系统为 PostalCode 分配的流变量值为 request.queryparam.postalcode。该值是一个字符串,因为变量赋值中没有 type 属性。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage name="GenerateGeocodingRequest">
        <AssignTo createNew="true" type="request">GeocodingRequest</AssignTo>
    <Set>
        <QueryParams>
            <QueryParam name="address">{request.queryparam.postalcode}</QueryParam>
            <QueryParam name="region">{request.queryparam.country}</QueryParam>
            <QueryParam name="sensor">false</QueryParam>
        </QueryParams>
        <Verb>GET</Verb>
    </Set>
    <AssignVariable>
        <Name>PostalCode</Name>
        <Ref>request.queryparam.postalcode</Ref>
    </AssignVariable>
    <AssignVariable>
        <Name>Country</Name>
        <Ref>request.queryparam.country</Ref>
    </AssignVariable>
</AssignMessage>

现在,请回想 ServiceCallout 政策<Request> 元素中使用的 PostalCode 变量:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout name="ExecuteGeocodingRequest">
    <Request variable="PostalCode"/>
    <Response>GeocodingResponse</Response>
    <HTTPTargetConnection>
        <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

由于 PostalCode 不是消息类型(在此示例中为字符串),因此您会收到错误代码:steps.servicecallout.RequestVariableNotMessageType

解决方法

确保在失败的 ServiceCallout 政策的 <Request> 元素中设置的变量是 message 类型流变量,或者您也可以直接在 ServiceCallout 政策中创建新的消息类型变量(请参阅 ServiceCallout 政策中的说明)并加以使用。

要更正政策,您必须修改 <Request> 元素,指定类型为消息的现有变量或新变量。例如,在分配政策政策中设置的变量 GeocodingRequest 为消息类型,则该变量可以在 ServiceCallout 政策中正常运行。例如:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout name="ExecuteGeocodingRequest">
    <Request variable="GeocodingRequest"/>
    <Response>GeocodingResponse</Response>
    <HTTPTargetConnection>
        <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

RequestVariableNotRequestMessageType

错误代码

steps.servicecallout.RequestVariableNotRequestMessageType

错误响应正文

{
    "fault": {
        "faultstring": "ServiceCallout[policy_name]: request variable [variable_name] value is not of type Request Message",
        "detail": {
            "errorcode": "steps.servicecallout.RequestVariableNotRequestMessageType"
        }
    }
}

原因

如果 ServiceCallout 策略<Request> 元素中指定的变量不是 message 类型,则会出现此错误。如果变量是响应消息类型、字符串或任何其他类型,您将会看到此错误。

message 类型变量代表所有 HTTP 请求和响应。内置流变量 requestresponsemessage 都属于 message 类型。

诊断

  1. 指出发生错误的 ServiceCallout 政策以及类型错误的变量名称。您可以在错误响应的 faultstring 元素中找到这两项。例如,在以下 faultstring 中,政策名称为 ExecuteGeocodingRequest,变量为 var_response

    "faultstring": "ServiceCallout[ExecuteGeocodingRequest]: request variable var_response value is not of type Message"

  2. 在失败的 ServiceCallout 政策 XML 中,验证 <Request> 元素中的变量名称是否与故障字符串中标识的变量名称(上方第 1 步中)一致。例如,以下政策指定了名为 var_response 的请求变量,该变量与 faultstring 中的相应内容一致:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ServiceCallout name="ExecuteGeocodingRequest">
        <Request variable="var_response"/>
        <Response>GeocodingResponse</Response>
        <HTTPTargetConnection>
            <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
        </HTTPTargetConnection>
    </ServiceCallout>
    
  3. 确定变量是否为请求消息类型:

    1. 在首次定义变量的 API 代理软件包中找到代码。
    2. 在大多数情况下,您会在另一个先于 ServiceCallout 政策执行的政策中发现问题变量已被创建并填充。例如,分配消息政策通常用于在 API 代理流程中创建和填充变量。
    3. 确定首次在其中定义并填充变量的政策后,您需要按以下方式确定该变量的类型:
      • 检查 type 属性的值(如果存在)。
      • 如果 type 属性不存在,则该变量将被视为字符串。
    4. 如果变量的类型不是请求消息 类型,则会导致错误。如需了解常见变量及其类型,请参阅流变量参考文档

例如,假设 ServiceCallout 政策中引用的 var_response 变量创建于以下所示的分配消息政策中。请注意,var_response 被授予的类型为 response。因此,var_response 变量的类型是响应消息。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage name="GenerateGeocodingRequest">
        <AssignTo createNew="true" type="request">GeocodingRequest</AssignTo>
    <AssignTo createNew="true" type="response">var_response</AssignTo>
    <Set>
        <QueryParams>
            <QueryParam name="address">{request.queryparam.postalcode}</QueryParam>
            <QueryParam name="region">{request.queryparam.country}</QueryParam>
            <QueryParam name="sensor">false</QueryParam>
        </QueryParams>
        <Verb>GET</Verb>
    </Set>
    <AssignVariable>
        <Name>PostalCode</Name>
        <Ref>request.queryparam.postalcode</Ref>
    </AssignVariable>
    <AssignVariable>
        <Name>Country</Name>
        <Ref>request.queryparam.country</Ref>
    </AssignVariable>
</AssignMessage>

请回想 ServiceCallout 政策的 <Request> 元素中使用的 var_response 变量。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout name="ExecuteGeocodingRequest">
    <Request variable="var_response"/>
    <Response>GeocodingResponse</Response>
    <HTTPTargetConnection>
        <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

由于 var_response 不是请求消息类型(其类型为响应消息),因此您会收到错误代码:steps.servicecallout.RequestVariableNotRequestMessageType

解决方法

确保在失败的 ServiceCallout 政策的 <Request> 元素中设置的变量是 message 类型变量,或者您也可以直接在 ServiceCallout 政策中创建新的请求消息类型变量(请参阅 ServiceCallout 政策中的说明)并加以使用。

如需更正政策,您必须修改 <Request> 元素,以指定类型为请求消息的现有变量或新变量,那么该变量可以在 ServiceCallout 政策中正常运行。例如:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout name="ExecuteGeocodingRequest">
    <Request variable="GeocodingRequest"/>
    <Response>GeocodingResponse</Response>
    <HTTPTargetConnection>
        <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

ExecutionFailed

错误代码

steps.servicecallout.ExecutionFailed

错误响应正文

{
    "fault": {
        "faultstring": "Execution of ServiceCallout [policy_name] failed. Reason: Host not reachable",
        "detail": {
            "errorcode": "steps.servicecallout.ExecutionFailed"
        }
    }
}

{
    "fault": {
        "faultstring": "Execution of ServiceCallout [policy_name] failed. Reason: ResponseCode [http_code] is treated as error",
        "detail": {
            "errorcode": "steps.servicecallout.ExecutionFailed"
        }
    }
}

可能的原因

造成此错误的可能原因包括:

原因 说明
网址无效或格式错误 ServiceCallout 政策中的目标网址格式错误,或者包含无效或无法访问的主机名。
后端服务器错误 后端服务器返回 4XX 或 5XX 错误响应。

原因:网址无效或格式错误

ServiceCallout 政策中的目标网址格式错误,或者包含无效或无法访问的主机名。

诊断

  1. 确定导致错误的 ServiceCallout 政策。错误响应的 faultstring 元素中会显示政策名称。例如,在以下 faultstring 中,失败的 ServiceCallout 政策名称是 ExecuteGeocodingRequest

    "faultstring": "ServiceCallout[ExecuteGeocodingRequest]"

  2. 在失败的 ServiceCallout 政策中,检查 <URL> 元素。如果该元素格式错误或包含无效或无法访问的主机名,则会导致此错误。例如,以下 ServiceCallout 政策列明了无效的 <URL>

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ServiceCallout name="ExecuteGeocodingRequest">
        <Request variable="GeocodingRequest"/>
        <Response>GeocodingResponse</Response>
        <HTTPTargetConnection>
            <URL>http://</URL>
        </HTTPTargetConnection>
    </ServiceCallout>
    

    <URL> 元素只包含 http:// 协议,但没有有效的主机名;因此,ServiceCallout 政策会失败,并显示以下错误:Execution of ServiceCallout ExecuteGeocodingRequest failed. Reason: Host not reachable

解决方法

确保失败的 ServiceCallout 政策中的 <URL> 元素包含具有可访问的主机名的有效网址。

如需更正上方显示的 ServiceCallout 政策,您可以修改 <URL> 元素以指定有效的网址:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout name="ExecuteGeocodingRequest">
    <Request variable="GeocodingRequest"/>
    <Response>GeocodingResponse</Response>
    <HTTPTargetConnection>
        <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

原因:后端服务器错误

后端服务器返回 4XX 或 5XX 错误响应。

诊断

  1. 确定导致错误的 ServiceCallout 政策。错误响应的 faultstring 元素中会显示政策名称。例如,在以下 faultstring 中,失败的 ServiceCallout 政策名称是 ExecuteGeocodingRequest

    "faultstring": "ServiceCallout[ExecuteGeocodingRequest]

  2. 检查错误响应正文中的 faultstring,并检查 Reason 中是否列出了任何 4XX 或 5XX 响应代码。例如,以下 faultstring 明确表示从后端服务器返回了响应代码 502:

    "faultstring": "Execution of ServiceCallout ExecuteGeocodingRequest failed. Reason: ResponseCode 502 is treated as error"

解决方法

确定错误响应代码后,您可以像解决任何 4XX 或 5XX 错误一样解决此问题。