500 内部服务器错误 - EmptyPath

您正在查看 Apigee Edge 文档。
前往 Apigee X 文档。
info

问题

客户端应用收到 HTTP 状态代码 500 Internal Server Error,并收到 错误代码 protocol.http.EmptyPath,以此响应 API 调用。

出错提示

客户端应用获取以下响应代码:

HTTP/1.1 500 Internal Server Error

此外,您可能会看到以下错误消息:

{
   "fault":{
      "faultstring":"Request path cannot be empty",
      "detail":{
         "errorcode":"protocol.http.EmptyPath"
      }
   }
}

可能的原因

如果后端服务器的请求网址(由流变量 target.url 表示)包含空路径,则会出现此错误。

根据规范 RFC 3986 第 3 节:语法组成部分 和 RFC 3986 第 3.3 节:路径:

  1. URI 语法 包含以下组成部分:

            foo://example.com:8042/over/there?name=ferret#nose
            \_/   \______________/\_________/ \_________/ \__/
             |            |            |            |       |
          scheme      authority       path        query   fragment
    
  2. path 组件是 必需的 ,并且必须始终包含正斜杠 (/),即使路径中没有其他字符也是如此。

因此,如果后端服务器的请求网址根本没有 path 组件,也就是说,它甚至没有正斜杠 (/),那么 Apigee Edge 会响应 500 Internal Server Error 和错误代码 protocol.http.EmptyPath。

例如:如果 target.url 的值为 https://www.mocktarget.apigee.net,则会发生此错误,因为 path 组件为空或缺失。

原因 说明 适用的问题排查说明
后端服务器网址 (target.url) 包含空路径 由流变量 target.url 表示的后端服务器网址包含空路径。 Edge Public 和 Private Cloud 用户

常见诊断步骤

请使用以下工具/方法之一来诊断此错误:

API 监控

过程 1:使用 API 监控

如需使用 API 监控诊断错误,请执行以下操作:

  1. 以具有 适当角色的用户身份 登录 Apigee Edge 界面。
  2. 切换到您要调查问题的组织。

  3. 依次前往分析 > API 监控 > 调查 页面。
  4. 选择您观察到错误的具体时间范围。
  5. 绘制故障代码 与时间 的关系图。

  6. 选择包含故障代码 protocol.http.EmptyPath 的单元格,如下所示:

  7. 系统会显示有关故障代码 protocol.http.EmptyPath 的信息,如下所示:

  8. 点击查看日志 以展开失败请求的行。

  9. 在日志 窗口中,记下以下详细信息:
    • 状态代码: 500
    • 故障来源 target
    • 故障代码 :protocol.http.EmptyPath
  10. 如果故障来源 为 target 且故障代码 为 protocol.http.EmptyPath,则表示后端服务器网址包含空路径。

跟踪记录

过程 2:使用跟踪工具

如需使用跟踪工具诊断错误,请执行以下操作:

  1. 启用 跟踪会话,然后执行以下任一操作:
    • 等待 500 Internal Server Error 错误发生,或
    • 如果您可以重现问题,请进行 API 调用以重现问题 500 Internal Server Error
  2. 确保已启用显示所有 FlowInfo :

  3. 选择其中一个失败的请求,然后检查跟踪记录。
  4. 浏览跟踪记录的不同阶段,找到发生故障的位置。
  5. 您通常会在目标请求流已启动 阶段之后的流中找到错误,如下所示:

  6. 记下跟踪记录中的错误值。

    error: Request path cannot be empty

    由于错误是在目标请求流已启动 阶段之后由 Apigee Edge 引发的, 表示后端服务器网址中的 path 为空。如果流变量 target.url(表示后端服务器的网址)可能已通过请求流中的某项政策更新为包含空路径,则很可能会发生这种情况。

  7. 从错误点向目标请求流已启动 阶段反向检查每个流中的读取和分配的变量 部分。
  8. 确定更新流变量 target.url 的政策。

    显示 JavaScript 政策更新了流变量 target.url 的跟踪记录示例:

    在上面显示的跟踪记录示例中,请注意流变量变量 target.url 的值在名为SetTargetURL的 JavaScript 政策中更新,如下所示:

    target.url : https://mocktarget.apigee.net
  9. 请注意,target.url 包含以下组成部分:
    • scheme :https://mocktarget.apigee.net
    • path :空
  10. 因此,您会收到错误 Request path cannot be empty。
  11. 在跟踪记录中前往 AX (记录的分析数据)阶段,然后点击该阶段。
  12. 向下滚动到 阶段详细信息 - 错误标头 部分,然后确定 X-Apigee-fault-code 和 X-Apigee-fault-source 的值,如下所示:

  13. 您将看到 X-Apigee-fault-code 和 X-Apigee-fault-source 的值分别为 protocol.http.EmptyPath 和 target ,这表示 此错误是由后端服务器网址包含空路径引起的。
    响应标头 值
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

NGINX

过程 3:使用 NGINX 访问日志

如需使用 NGINX 访问日志诊断错误,请执行以下操作:

  1. 如果您是 Private Cloud 用户,则可以使用 NGINX 访问日志来确定 有关 HTTP 500 Internal Server Error 的关键信息。
  2. 检查 NGINX 访问日志:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

  3. 搜索以查看在特定时间段内(如果问题过去发生过)是否存在任何错误代码 protocol.http.EmptyPath 的 500 错误,或者是否存在任何请求仍然失败并显示 500。
  4. 如果您确实发现任何 500 错误,且 X-Apigee-fault-code 与 protocol.http.EmptyPath 的值匹配,请确定 X-Apigee-fault-source 的值。

    NGINX 访问日志中的 500 错误示例:

    NGINX 访问日志中的上述示例条目具有以下 X- Apigee-fault-code 和 X-Apigee-fault-source: 值:

    标头 值
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

    请注意,X-Apigee-fault-code 和 X-Apigee-fault-source 的值分别为 protocol.http.EmptyPath 和 target ,这表示 此错误是由后端服务器网址包含空路径引起的。

原因:后端服务器网址 (target.url) 包含空路径

诊断

  1. 使用 API 监控、跟踪工具或 NGINX 访问日志(如 常见诊断步骤中所述)确定 500 Internal Server Error故障代码 和故障来源。
  2. 如果故障代码 为 protocol.http.EmptyPath 且故障来源 的值 为 target,则表示后端服务器网址包含空 路径。
  3. 后端服务器网址由 Apigee Edge 中的流变量 target.url 表示。如果您尝试使用目标请求流中的任何政策(在 代理/共享流中) target.url 动态 更新后端服务器网址(即 `target.url`),使其包含空路径 ,则通常会发生此错误。

  4. 使用以下步骤之一确定流变量 target.url 是否确实包含空路径及其值的 来源:

    跟踪记录

    使用跟踪工具

    如果您已捕获此错误的跟踪记录,请使用 使用跟踪工具 中所述的步骤,并执行以下操作:

    1. 验证 target.url 是否包含空路径。
    2. 如果是,请找出哪个政策修改或更新了 target.url的值以包含空路径。

      显示 JavaScript 政策更新了流变量 target.url: 的跟踪记录示例:

    3. 在上面的跟踪记录示例中,请注意 JavaScript 政策已修改或 更新了 target.url 的值以包含空路径。
    4. 请注意,target.url 包含以下组成部分:
      • scheme: https://mocktarget.apigee.net
      • path :空

    日志

    在日志服务器中使用日志

    1. 如果您没有此错误的跟踪记录(间歇性问题),请检查您是否已使用 MessageLogging 或 ServiceCallout 等政策将有关流变量 target.url 值的信息记录到日志服务器中。
    2. 如果您有日志,请查看这些日志并执行以下操作:
      1. 验证 target.url 是否包含空路径,以及
      2. 查看您是否可以确定哪个政策修改了 target.url 以包含空路径

    API 代理

    查看失败的 API 代理

    如果您没有此错误的跟踪记录或日志,请查看失败的 API 代理,以确定是什么修改或更新了流变量 target.url 以包含 无效路径。请检查以下事项:

    • API 代理中的政策
    • 从代理调用的任何共享流
  5. 仔细检查修改或 更新流变量 target.url 的特定政策(例如 AssignMessage 或 JavaScript),并确定将 target.url 更新为包含空路径的原因。

    以下是一些示例政策,这些政策会错误地更新流变量 target.url 以包含空路径,从而导致此错误。

    示例 1

    示例 1:JavaScript 政策更新 target.url 变量

    var url = "https://mocktarget.apigee.net"
    context.setVariable("target.url", url);

    在上面的示例中,请注意流变量 target.url 已使用另一个变量 url 中包含的值 https://mocktarget.apigee.net 进行更新。

    请注意,target.url 包含以下组成部分:

    • scheme :https://mocktarget.apigee.net
    • path :空

    由于路径为空,Apigee Edge 会返回 500 Internal Server Error,并返回 错误代码 protocol.http.EmptyPath。

    示例 2

    示例 2:JavaScript 政策更新 target.url 变量

    var path = context.getVariable("request.header.Path");
    var url = "https://mocktarget.apigee.net" + path
    context.setVariable("target.url", url);

    在上面的示例中,请注意流变量 target.url 通过 串联变量 url 中包含的值 https://mocktarget.apigee.net 和 另一个变量 path 的值进行更新,该 变量的值是从 request.header.Path. 中检索的。

    如果您有权访问实际请求或跟踪记录,则可以验证传递给 request.header.Path 的实际值 。

    用户发出的示例请求:

    curl -v https://HOST_ALIAS/v1/myproxy -H "Authorization: Bearer <token>
    

    在此示例中,标头路径未作为请求的一部分发送。因此,JavaScript 政策中变量路径的值为 null。

    因此:

    • url = https://mocktarget.apigee.net + path
    • url = https://mocktarget.apigee.net + null
    • target.url = https://mocktarget.apigee.netnull

    请注意,target.url 包含以下组成部分:

    • scheme: https://mocktarget.apigee.netnull
    • path :空

    示例 3

    示例 3:AssignMessage 政策通过target.url 另一个变量更新变量

    <AssignMessage async="false" continueOnError="false" enabled="true" name=">AM-SetTargetURL">
        <DisplayName>AM-SetTargetURL</DisplayName>
        <AssignVariable>
             <Name>target.url</Name>
             <Value>https://mocktarget.apigee.net</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
        <AssignTo createNew="false" transport="http" type="request"/>
    </AssignMessage>

    请注意,target.url 包含以下组成部分:

    • scheme :https://mocktarget.apigee.net
    • path :空

    在上述所有示例中,后端服务器网址中的路径(即 target.url)为空,因此 Apigee Edge 会返回 500 Internal Server Error,并返回错误代码 protocol.http.EmptyPath。

解决方法

根据规范 RFC 3986 第 2 节:语法组成部分,path 组件是 必需的,并且必须始终包含正斜杠 (`/`),即使 path 中没有其他字符也是如此。请执行以下步骤来 解决此问题:

  1. 确保由流变量 target.url 表示的后端服务器网址始终包含 非空路径。
    1. 在某些情况下,路径中可能没有资源名称,那么请确保路径 至少包含正斜杠 (/)。
    2. 如果您使用任何其他变量来确定流变量 target.url的值,请确保其他变量不包含空路径。
    3. 如果您执行任何字符串运算来确定流变量 target.url的值,请确保字符串 运算的结果或输出不包含空路径。
  2. 在诊断中讨论的示例中,您可以按如下所述解决此问题:

    示例 1

    示例 1:JavaScript 政策更新 target.url 变量

    将正斜杠 (/) 添加到变量 url 以解决此 问题,如下所示:

    var url = "https://mocktarget.apigee.net/"
    context.setVariable("target.url", url);

    示例 2

    示例 2:JavaScript 政策更新 target.url 变量

    var path = context.getVariable("request.header.Path");
    var url = "https://mocktarget.apigee.net" + path
    context.setVariable("target.url", url);

    确保您传递有效的路径(例如 /iloveapis)作为 请求标头 Path 的一部分,以解决此问题,如下所示:

    示例请求:

    curl -v https://HOST_ALIAS/v1/myproxy -H "Authorization: Bearer <token> -H "Path: /iloveapis"
    

    示例 3

    示例 3:AssignMessage 政策通过target.url 另一个变量更新变量

    在 AssignMessage 政策的 <Value> 元素中添加有效路径。例如,您可以将 /json 作为 MockTarget API 的路径。也就是说,将 <Value> 元素修改为 https://mocktarget.apigee.net/json,如下所示:

    <AssignMessage async="false" continueOnError="false" enabled="true" name="AM-SetTargetURL">
        <DisplayName>AM-SetTargetURL</DisplayName>
        <AssignVariable>
             <Name>target.url</Name>
             <Value>https://mocktarget.apigee.net/json</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
        <AssignTo createNew="false" transport="http" type="request"/>
    </AssignMessage>

规范

Apigee Edge 期望后端服务器网址 不包含空路径 ,具体规范如下:

规范
RFC 3986 第 3 节:语法组成部分
RFC 3986 第 3.3 节:路径

如果您仍然需要 Apigee 支持团队的任何帮助,请前往 必须收集诊断信息。

必须收集的诊断信息

如果按照上述说明操作后问题仍然存在,请收集以下 诊断信息,然后联系 Apigee Edge 支持团队。

如果您是 Public Cloud 用户,请提供以下信息:

  • 组织名称
  • 环境名称
  • API 代理名称
  • 用于重现 500 Internal Server Error(错误代码为 protocol.http.EmptyPath)的完整 curl 命令
  • API 请求的跟踪记录文件

如果您是 Private Cloud 用户,请提供以下信息:

  • 针对失败请求观察到的完整错误消息
  • 环境名称
  • API 代理软件包
  • API 请求的跟踪记录文件
  • NGINX 访问日志:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    其中: ORG、ENV 和 PORT# 替换为 实际值。

  • 消息处理器系统日志 /opt/apigee/var/log/edge-message- processor/logs/system.log

参考

流变量 - 目标