Error handling

Deliver a more consistent user experience by proactively interpreting and responding to errors. Whether you're developing automated cloud workflows or interacting with remote APIs, the Rust client libraries provide ways to gracefully handle errors. This guide explains how to:

  • Handle errors: Inspect error types and branch your application logic based on service status codes, such as creating a missing resource when encountering a NotFound error.
  • Examine error details: Extract and examine rich error details—such as bad request field violations or quota failures—returned by Google Cloud services to troubleshoot API issues and dynamically adjust runtime behavior.
  • Resolve binding errors: Interpret and resolve client-side HTTP binding errors caused by invalid or missing request fields to ensure your requests reach the service smoothly.

Prerequisites

This guide uses the Secret Manager service and the Cloud Natural Language API to demonstrate error handling. To run the examples, first:

  1. Enable the Secret Manager service.
  2. Enable the Cloud Natural Language API.
  3. Set up authentication.

Dependencies

Use the following command to add the required dependencies to your Cargo.toml file:

cargo add google-cloud-secretmanager-v1 google-cloud-gax crc32c google-cloud-language-v2

Handle errors

The Rust client libraries let you surface and react to errors. You might, for example, use error discovery to branch behavior: a common pattern in cloud services is to use a resource as if the container for it existed, only creating the container if you encounter an error. If the container usually exists, this approach is more efficient than checking whether the container exists before making the request.

The following example demonstrates how to handle a missing resource by catching the error when attempting to update a Secret Manager secret—and creating it if it doesn't already exist.

  1. Make an attempt to create a new secret version:

    match update_attempt(&client, project_id, secret_id, data.clone()).await {

  2. If update_attempt succeeds, print the successful result and return:

    Ok(version) => {
        println!("new version is {}", version.name);
        Ok(version)
    }

  3. If update_attempt fails, you must disambiguate the cause of the failure. The request might have failed for many reasons, such as a dropped connection or error with authentication tokens. Retry policies can deal with most of these errors. Look for errors returned by the service:

    Err(e) => {
        if let Some(status) = e.downcast_ref::<Error>().and_then(|e| e.status()) {

  4. Look for an error that corresponds with a missing secret:

    if status.code == Code::NotFound {

  5. If you have encountered a "not found" error (Code::NotFound), try to create the secret:

    let _ = create_secret(&client, project_id, secret_id).await?;

  6. Try to add the secret version again. This time, return an error if anything fails:

    let version = update_attempt(&client, project_id,