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
- Learn how to handle binding errors that occur when a client library can't find a URI to match an HTTP request.
- Learn how to work with List operations.
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(())
}