通过主动解读错误并做出响应,提供更一致的用户体验。无论您是在开发自动云工作流还是与远程 API 交互,Rust 客户端库都提供了妥善处理错误的方法。本指南介绍了如何:
- 处理错误: 检查错误类型,并根据服务状态代码(例如在遇到
NotFound错误时创建缺失的资源)分支应用逻辑。 - 检查错误详情: 提取并检查服务 Google Cloud 返回的丰富错误详情(例如错误 请求字段违规或配额失败),以排查 API 问题并动态调整运行时行为。
- 解决绑定错误: 解读并解决因请求字段无效或缺失而导致的客户端 HTTP 绑定错误,确保您的请求顺利到达服务。
前提条件
本指南使用 Secret Manager 服务和 Cloud Natural Language API来演示错误处理。如需运行示例,请先执行以下操作:
- 启用 Secret Manager 服务。
- 启用 Cloud Natural Language API。
- 设置身份验证。
依赖项
使用以下命令将所需的依赖项添加到 Cargo.toml 文件:
cargo add google-cloud-secretmanager-v1 google-cloud-gax crc32c google-cloud-language-v2
处理错误
Rust 客户端库可让您发现错误并做出响应。例如,您可以使用错误发现来分支行为:云服务中的常见模式是使用资源,就好像其容器存在一样,仅在遇到错误时才创建容器。如果容器通常存在,则此方法比在发出请求之前检查容器是否存在更高效。
以下示例演示了如何在尝试更新 Secret Manager 密文时捕获错误,并在密文尚不存在时创建它,从而处理缺失的资源。
尝试创建新的密文版本:
如果
update_attempt成功,请输出成功结果并返回:如果
update_attempt失败,您必须消除失败原因的歧义。 请求可能会因多种原因而失败,例如连接断开或身份验证令牌出错。重试政策可以处理大多数此类错误。查找服务返回的错误:查找与缺失的密文对应的错误:
如果您遇到“未找到”错误 (
Code::NotFound),请尝试创建密文:尝试再次添加密文版本。这次,如果任何操作失败,则返回错误:
代码示例:main 函数 (sample)
此示例的完整代码分为三个部分:主编排函数 (sample),后跟其两个辅助方法 (update_attempt 和 create_secret)。
sample 函数尝试向密文添加新版本。它会捕获客户端返回的错误,并检查该错误是否为 Code::NotFound 错误。如果未找到密文,该函数会创建最初缺失的密文并重试更新。
代码示例:辅助方法 (update_attempt)
辅助方法 update_attempt 尝试添加密文版本,计算载荷数据的 CRC32c 校验和:
代码示例:辅助方法 (create_secret)
辅助方法 create_secret 会创建缺失的密文并配置自定义重试政策:
检查错误详情
某些 Google Cloud 服务会在请求失败时提供其他错误详情。
为了帮助进行问题排查,Rust 客户端库在使用 std::fmt::Display 格式化错误时会包含这些详情。您可以检查这些详情并相应地更改应用行为。
只有服务返回的错误包含详细信息。客户端
库会返回一个
StatusDetails
枚举,其中包含不同类型的错误详情。
提取错误详情
此示例有意向 Cloud Natural Language API 发送错误请求,并检查生成的错误。
创建客户端:
发送请求(在此示例中,缺少键字段):
使用标准 Rust 函数从结果中提取错误。 错误类型以易于用户理解的形式输出所有错误详情:
输出类似于以下内容:
request failed with error Error {
kind: Service {
status_code: Some(
400,
),
headers: Some(
{
"vary": "X-Origin",
"vary": "Referer",
"vary": "Origin,Accept-Encoding",
"content-type": "application/json; charset=UTF-8",
"date": "Sat, 24 May 2025 17:19:49 GMT",
"server": "scaffolding on HTTPServer2",
"x-xss-protection": "0",
"x-frame-options": "SAMEORIGIN",
"x-content-type-options": "nosniff",
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
"accept-ranges": "none",
"transfer-encoding": "chunked",
},
),
status: Status {
code: InvalidArgument,
message: "One of content, or gcs_content_uri must be set.",
details: [
BadRequest(
BadRequest {
field_violations: [
FieldViolation {
field: "document.content",
description: "Must have some text content to annotate.",
reason: "",
localized_message: None,
_unknown_fields: {},
},
],
_unknown_fields: {},
},
),
],
},
},
}
以编程方式检查错误详情
有时,您可能需要以编程方式检查错误详情。此示例会遍历数据结构并输出最相关的字段。
只有服务返回的错误包含详细信息,因此请先查询错误,查看其是否包含正确的错误类型。如果包含,您可以分解有关该错误的一些顶级信息:
遍历详情:
如前所述,客户端库会返回一个
StatusDetails
枚举,其中包含不同类型的错误详情。此示例仅检查 BadRequest 错误:
BadRequest 包含违规字段的列表。您可以遍历并输出每个字段的详情:
此类信息在开发期间可能很有用。
StatusDetails 的其他分支(例如
QuotaFailure)在运行时可能会用于限制应用。
预期输出
错误详情的输出类似于以下内容:
status.code=400, status.message=One of content, or gcs_content_uri must be set., status.status=Some("INVALID_ARGUMENT")
the request field document.content has a problem: "Must have some text content to annotate."
代码示例:检查错误详情
sample 函数有意向 Cloud Natural Language API 发送无效请求,以生成服务错误。然后,它会捕获错误并以编程方式提取 StatusDetails,以检查和输出特定的 BadRequest 字段违规。
解决绑定错误
使用 HTTP 向 Google Cloud 服务发送请求时,请求会使用 统一资源标识符 (URI) 来指定资源。某些 RPC 对应于多个 URI,请求的内容决定了使用哪个 URI。
客户端库会考虑所有可能的 URI,并且仅在没有 URI 可用时返回绑定错误。通常,当字段缺失或格式无效时,会发生这种情况。
如果您的请求未能为任何可能的 URI 提供包含有效格式的字段,您可能会遇到绑定错误:
Error: cannot find a matching binding to send the request: at least one of the
conditions must be met: (1) field `name` needs to be set and match the template:
'projects/*/secrets/*' OR (2) field `name` needs to be set and match the
template: 'projects/*/locations/*/secrets/*'
上述示例错误之所以发生,是因为该示例尝试检索资源的详细信息,但未提供其名称。具体而言,name 字段
在 GetSecretRequest
上是必需的,但该示例未设置该字段:
如何修正绑定错误
如需修正该错误,请设置必填字段,使其与错误消息中显示的其中一个模板匹配:
'projects/*/secrets/*''projects/*/locations/*/secrets/*'
任一模板都允许客户端库向服务器发出请求。例如,以下代码与第一个模板匹配:
或者,以下代码与第二个模板匹配:
解读模板
绑定错误的错误消息包含模板字符串,这些字符串显示了请求字段的可能值。大多数模板字符串都包含 * 和 ** 作为
通配符来匹配字段值。
单通配符
* 通配符本身表示不带 / 的非空字符串。您可以将其视为正则表达式 [^/]+。
下面是一些示例:
| 模板 | 输入 | 匹配? |
|---|---|---|
* |
simple-string-123 |
true |
projects/* |
projects/p |
true |
projects/*/locations |
projects/p/locations |
true |
projects/*/locations/* |
projects/p/locations/l |
true |
* |
""(空) |
false |
* |
string/with/slashes |
false |
projects/* |
projects/(空) |
false |
projects/* |
projects/p/(额外的斜杠) |
false |
projects/* |
projects/p/locations/l |
false |
projects/*/locations |
projects/p |
false |
projects/*/locations |
projects/p/locations/l |
false |
双通配符
** 通配符不太常见,表示任何字符串。该字符串可以为
空,也可以包含任意数量的斜杠 (/)。您可以将其视为
正则表达式 .*。
如果模板以 /** 结尾,则初始斜杠是可选的。
| 模板 | 输入 | 匹配? |
|---|---|---|
** |
"" |
true |
** |
simple-string-123 |
true |
** |
string/with/slashes |
true |
projects/*/** |
projects/p |
true |
projects/*/** |
projects/p/locations |
true |
projects/*/** |
projects/p/locations/l |
true |
projects/*/** |
locations/l |
false |
projects/*/** |
projects//locations/l |
false |
检查绑定错误
如果您需要以编程方式检查错误,请检查该错误是否为绑定错误,并将其向下转换为 BindingError:
后续步骤
- 了解如何配置重试政策。