Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Examine error details

Some Google Cloud services include additional error details when requests fail. To help with any troubleshooting, the Google Cloud client libraries for Rust always include these details when errors are formatted using std::fmt::Display. Some applications may want to examine these details and change their behavior based on their contents.

This guide shows you how to examine the error details returned by Google Cloud services.

Prerequisites

This guide uses the Cloud Natural Language API to show error details, but the concepts apply to other services as well.

You may want to follow the service quickstart, which shows you how to enable the service and set up authentication.

For complete setup instructions for the Rust libraries, see Setting up your development environment.

Dependencies

As usual with Rust, you must declare the dependency in your Cargo.toml file:

cargo add google-cloud-language-v2

Examining error details

You'll create a request that intentionally results in an error, and then examine the error contents. First, create a client:

    use google_cloud_language_v2 as lang;
    let client = lang::client::LanguageService::builder().build().await?;

Then send a request. In this case, a key field is missing:

    let result = client
        .analyze_sentiment()
        .set_document(
            lang::model::Document::new()
                // Missing document contents
                // .set_content("Hello World!")
                .set_type(lang::model::document::Type::PlainText),
        )
        .send()
        .await;

Extract the error from the result, using standard Rust functions. The error type prints all the error details in human-readable form:

    let err = result.expect_err("the request should have failed");
    println!("\nrequest failed with error {err:#?}");

This should produce output similar to:

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: {},
                    },
                ),
            ],
        },
    },
}

Programmatically examining the error details

Sometimes you may need to examine the error details programmatically. The rest of the example traverses the data structure and prints the most relevant fields.

Only errors returned by the service contain detailed information, so first query the error to see if it contains the correct error type. If it does, you can break down some top-level information about the error:

    if let Some(status) = err.status() {
        println!(
            "  status.code={}, status.message={}",
            status.code, status.message,
        );

And then iterate over all the details:

        for detail in status.details.iter() {
            use google_cloud_gax::error::rpc::StatusDetails;
            match detail {

The client libraries return a StatusDetails enum with the different types of error details. This example only examines BadRequest errors:

                StatusDetails::BadRequest(bad) => {

A BadRequest contains a list of fields that are in violation. You can iterate and print the details for each:

                    for f in bad.field_violations.iter() {
                        println!(
                            "  the request field {} has a problem: \"{}\"",
                            f.field, f.description
                        );
                    }

Such information can be useful during development. Other branches of StatusDetails such as QuotaFailure may be useful at runtime to throttle an application.

Expected output

Typically the output from the error details will look like so:

  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."

What's next


Examining error details: complete code

pub async fn examine_error_details() -> crate::Result<()> {
    use google_cloud_language_v2 as lang;
    let client = lang::client::LanguageService::builder().build().await?;

    let result = client
        .analyze_sentiment()
        .set_document(
            lang::model::Document::new()
                // Missing document contents
                // .set_content("Hello World!")
                .set_type(lang::model::document::Type::PlainText),
        )
        .send()
        .await;

    let err = result.expect_err("the request should have failed");
    println!("\nrequest failed with error {err:#?}");

    if let Some(status) = err.status() {
        println!(
            "  status.code={}, status.message={}",
            status.code, status.message,
        );
        for detail in status.details.iter() {
            use google_cloud_gax::error::rpc::StatusDetails;
            match detail {
                StatusDetails::BadRequest(bad) => {
                    for f in bad.field_violations.iter() {
                        println!(
                            "  the request field {} has a problem: \"{}\"",
                            f.field, f.description
                        );
                    }
                }
                _ => {
                    println!("  additional error details: {detail:?}");
                }
            }
        }
    }

    Ok(())
}