8#include <google/protobuf/any.pb.h>
9#include <google/protobuf/message.h>
10#include <google/rpc/error_details.pb.h>
11#include <google/rpc/status.pb.h>
12#include <grpcpp/support/status.h>
14USERVER_NAMESPACE_BEGIN
41class RichStatus
final {
57 template <
typename... TDetails>
58 RichStatus(grpc::StatusCode code, std::string message, TDetails&&... details);
63 template <
typename TDetail>
76 template <
typename TRichErrorDetail>
77 [[nodiscard]]
static std::optional<TRichErrorDetail>
TryGetDetail(
const google::rpc::Status& status);
79 [[nodiscard]]
const google::rpc::Status& GetGoogleStatus()
const& {
return google_status_; }
80 google::rpc::Status GetGoogleStatus() && {
return std::move(google_status_); }
86 [[nodiscard]]
explicit operator grpc::Status()
const {
return ToGrpcStatus(); }
89 google::rpc::Status google_status_;
120 std::unordered_map<std::string, std::string>
metadata;
122 google::rpc::ErrorInfo ToGoogleErrorDetail()
const&;
123 google::rpc::ErrorInfo ToGoogleErrorDetail() &&;
125 static std::optional<
ErrorInfo> TryUnpack(
const google::protobuf::Any& any);
139 google::rpc::RetryInfo ToGoogleErrorDetail()
const;
141 static std::optional<
RetryInfo> TryUnpack(
const google::protobuf::Any& any);
151 std::vector<std::string> stack_entries;
154 google::rpc::DebugInfo ToGoogleErrorDetail()
const&;
155 google::rpc::DebugInfo ToGoogleErrorDetail() &&;
157 static std::optional<
DebugInfo> TryUnpack(
const google::protobuf::Any& any);
183 google::rpc::QuotaFailure ToGoogleErrorDetail()
const&;
184 google::rpc::QuotaFailure ToGoogleErrorDetail() &&;
186 static std::optional<
QuotaFailure> TryUnpack(
const google::protobuf::Any& any);
227 google::rpc::PreconditionFailure ToGoogleErrorDetail()
const&;
228 google::rpc::PreconditionFailure ToGoogleErrorDetail() &&;
255 google::rpc::BadRequest ToGoogleErrorDetail()
const&;
256 google::rpc::BadRequest ToGoogleErrorDetail() &&;
258 static std::optional<
BadRequest> TryUnpack(
const google::protobuf::Any& any);
273 std::string request_id;
274 std::string serving_data;
276 google::rpc::RequestInfo ToGoogleErrorDetail()
const&;
277 google::rpc::RequestInfo ToGoogleErrorDetail() &&;
279 static std::optional<
RequestInfo> TryUnpack(
const google::protobuf::Any& any);
306 google::rpc::ResourceInfo ToGoogleErrorDetail()
const&;
307 google::rpc::ResourceInfo ToGoogleErrorDetail() &&;
309 static std::optional<
ResourceInfo> TryUnpack(
const google::protobuf::Any& any);
316 std::string description;
336 google::rpc::Help ToGoogleErrorDetail()
const&;
337 google::rpc::Help ToGoogleErrorDetail() &&;
339 static std::optional<
Help> TryUnpack(
const google::protobuf::Any& any);
368 google::rpc::LocalizedMessage ToGoogleErrorDetail()
const&;
369 google::rpc::LocalizedMessage ToGoogleErrorDetail() &&;
371 static std::optional<
LocalizedMessage> TryUnpack(
const google::protobuf::Any& any);
374template <
typename... TDetails>
375RichStatus::
RichStatus(grpc::StatusCode code, std::string message, TDetails&&... details) {
376 google_status_.set_code(
static_cast<
int>(code));
377 google_status_.set_message(std::move(message));
378 (AddDetail(std::forward<TDetails>(details)), ...);
381template <
typename TDetail>
383 const auto pb_google_detail = std::forward<TDetail>(detail).ToGoogleErrorDetail();
384 google_status_.add_details()->PackFrom(pb_google_detail);
388template <
typename TRichErrorDetail>
389std::optional<TRichErrorDetail> RichStatus::
TryGetDetail(
const google::rpc::Status& status) {
390 for (
const auto& detail : status.details()) {
391 const auto rich_error_detail_opt = TRichErrorDetail::TryUnpack(detail);
392 if (rich_error_detail_opt) {
393 return *rich_error_detail_opt;