16 个版本 (9 个重大更新)
0.12.1 | 2024年7月17日 |
---|---|
0.11.0 | 2024年2月8日 |
0.10.2 | 2023年9月28日 |
0.9.2 | 2023年4月17日 |
0.1.0 | 2020年7月8日 |
#5 in #grpc-server
每月下载量 104,112
在 5 个 crate 中使用 (4 个直接使用)
615KB
12K SLoC
tonic-types
一组可用来与 tonic
一起使用的实用 protobuf 类型。
此 crate 还引入了 StatusExt
trait 并在 tonic::Status
中实现它,允许以方便的方式使用 tonic
实现 gRPC 丰富的错误模型。
用法
有用的 protobuf 类型通过 pb
模块提供。它们可以直接导入和工作。
StatusExt
trait 为 tonic::Status
添加了关联函数,可以在服务器端使用这些函数创建带有错误详细信息的状态,然后将其返回给 gRPC 客户端。此外,该 trait 还为 tonic::Status
添加了方法,这些方法可以由 tonic 客户端使用以提取错误详细信息,并轻松处理它们。
入门指南
[dependencies]
tonic = <tonic-version>
tonic-types = <tonic-types-version>
示例
下面的示例涵盖了 gRPC 丰富的错误模型 的基本用法。更完整的服务器和客户端实现可以在主仓库中的 Richer Error 示例 中找到,位于 examples 目录。
服务器端:使用 tonic::Status
和 ErrorDetails
结构生成
use tonic::{Code, Status};
use tonic_types::{ErrorDetails, StatusExt};
// ...
// Inside a gRPC server endpoint that returns `Result<Response<T>, Status>`
// Create empty `ErrorDetails` struct
let mut err_details = ErrorDetails::new();
// Add error details conditionally
if some_condition {
err_details.add_bad_request_violation(
"field_a",
"description of why the field_a is invalid"
);
}
if other_condition {
err_details.add_bad_request_violation(
"field_b",
"description of why the field_b is invalid",
);
}
// Check if any error details were set and return error status if so
if err_details.has_bad_request_violations() {
// Add additional error details if necessary
err_details
.add_help_link("description of link", "https://resource.example.local")
.set_localized_message("en-US", "message for the user");
let status = Status::with_error_details(
Code::InvalidArgument,
"bad request",
err_details,
);
return Err(status);
}
// Handle valid request
// ...
客户端:从 ErrorDetails
结构体中提取 tonic::Status
use tonic::{Response, Status};
use tonic_types::StatusExt;
// ...
// Where `req_result` was returned by a gRPC client endpoint method
fn handle_request_result<T>(req_result: Result<Response<T>, Status>) {
match req_result {
Ok(response) => {
// Handle successful response
},
Err(status) => {
let err_details = status.get_error_details();
if let Some(bad_request) = err_details.bad_request() {
// Handle bad_request details
}
if let Some(help) = err_details.help() {
// Handle help details
}
if let Some(localized_message) = err_details.localized_message() {
// Handle localized_message details
}
}
};
}
处理不同错误消息类型
在 ErrorDetails
文档中提供了多个示例。如何在标准错误消息类型的字段中使用正确指令的说明可以在 error_details.proto 中找到。
替代的 tonic::Status
相关函数和方法
在 StatusExt
文档中,展示了与 tonic::Status
交互的替代方式,使用包装在 ErrorDetail
枚举中的错误详情结构体的向量。这种方法可以提供对将生成或已接收的标准错误消息向量有更多控制。要了解如何采用这种方法,请查看 StatusExt::with_error_details_vec
和 StatusExt::get_error_details_vec
文档,以及主仓库的 Richer Error 示例 目录。
除此之外,StatusExt
文档中提供了多个使用替代错误详情提取方法的示例,如果客户端只处理一种标准错误消息,这可能会特别有用。例如,使用 StatusExt::get_details_bad_request
从 tonic::Status
中提取 BadRequest
错误消息是一种更直接的方法。
依赖项
~4.5–6MB
~104K SLoC