主動解讀並回應錯誤,提供更一致的使用者體驗。無論您是開發自動化雲端工作流程,還是與遠端 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),請嘗試建立密鑰:請嘗試再次新增 Secret 版本。這次,如果發生任何錯誤,請傳回錯誤:
程式碼範例:主要函式 (sample)
本範例的完整程式碼分為三部分:主要協調函式 (sample),以及兩個輔助方法 (update_attempt 和 create_secret)。
sample 函式會嘗試將新版本新增至密鑰。這個函式會擷取用戶端傳回的錯誤,並檢查錯誤是否為 Code::NotFound 錯誤。如果找不到密碼,函式會建立最初遺失的密碼,然後重試更新。
程式碼範例:輔助方法 (update_attempt)
輔助方法 update_attempt 會嘗試新增密鑰版本,並計算酬載資料的 CRC32c 總和檢查碼:
程式碼範例:輔助方法 (create_secret)
輔助方法 create_secret 會建立缺少的密鑰,並設定自訂重試政策:
檢查錯誤詳細資料
部分 Google Cloud 服務會在要求失敗時提供額外的錯誤詳細資料。為協助排解問題,使用 std::fmt::Display 格式化錯誤時,Rust 用戶端程式庫會提供這些詳細資料。您可以檢查這些詳細資料,並據此變更應用程式行為。
只有服務傳回的錯誤包含詳細資訊。用戶端程式庫會傳回 StatusDetails 列舉,其中包含不同類型的錯誤詳細資料。
擷取錯誤詳細資料
這個範例會刻意將錯誤要求傳送至 Cloud Natural Language API,並檢查產生的錯誤。
建立用戶端: <0x0A
傳送要求 (在本範例中,缺少主要欄位):
使用標準 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/*'
上述範例錯誤是因為範例嘗試擷取資源詳細資料,但未提供資源名稱。具體來說,GetSecretRequest 的 name 欄位為必填,但範例未設定:
如何修正繫結錯誤
如要修正錯誤,請設定必要欄位,使其符合錯誤訊息中顯示的其中一個範本:
'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:
後續步驟
- 瞭解如何設定重試政策。