aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpc++
diff options
context:
space:
mode:
authorGravatar Noah Eisen <ncteisen@gmail.com>2017-12-08 13:44:37 -0800
committerGravatar GitHub <noreply@github.com>2017-12-08 13:44:37 -0800
commit5b1a66cef125ef0dcc99c792a52ce76bc380564a (patch)
treea07455792bd59a8d44d7415fc3c313a22c764db6 /include/grpc++
parent94e676e10f8c739289924b8458a246699e3623ce (diff)
parent6193c63dabf37023bd9a985f2db807f0551dd1ef (diff)
Merge pull request #13413 from ncteisen/surfacing-error-details-wrapped
Surface Error String to Wrapped Languages
Diffstat (limited to 'include/grpc++')
-rw-r--r--include/grpc++/impl/codegen/call.h15
-rw-r--r--include/grpc++/impl/codegen/client_context.h14
2 files changed, 26 insertions, 3 deletions
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index af2c2b510c..e581049e7f 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -558,10 +558,12 @@ class CallOpRecvInitialMetadata {
class CallOpClientRecvStatus {
public:
- CallOpClientRecvStatus() : recv_status_(nullptr) {}
+ CallOpClientRecvStatus()
+ : recv_status_(nullptr), debug_error_string_(nullptr) {}
void ClientRecvStatus(ClientContext* context, Status* status) {
- metadata_map_ = &context->trailing_metadata_;
+ client_context_ = context;
+ metadata_map_ = &client_context_->trailing_metadata_;
recv_status_ = status;
error_message_ = g_core_codegen_interface->grpc_empty_slice();
}
@@ -574,7 +576,7 @@ class CallOpClientRecvStatus {
op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
op->data.recv_status_on_client.status = &status_code_;
op->data.recv_status_on_client.status_details = &error_message_;
- op->data.recv_status_on_client.error_string = nullptr;
+ op->data.recv_status_on_client.error_string = &debug_error_string_;
op->flags = 0;
op->reserved = NULL;
}
@@ -592,13 +594,20 @@ class CallOpClientRecvStatus {
grpc::string(GRPC_SLICE_START_PTR(error_message_),
GRPC_SLICE_END_PTR(error_message_)),
binary_error_details);
+ client_context_->set_debug_error_string(
+ debug_error_string_ != nullptr ? debug_error_string_ : "");
g_core_codegen_interface->grpc_slice_unref(error_message_);
+ if (debug_error_string_ != nullptr) {
+ g_core_codegen_interface->gpr_free((void*)debug_error_string_);
+ }
recv_status_ = nullptr;
}
private:
+ ClientContext* client_context_;
MetadataMap* metadata_map_;
Status* recv_status_;
+ const char* debug_error_string_;
grpc_status_code status_code_;
grpc_slice error_message_;
};
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index 22b581cbc5..61d97ce818 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -348,6 +348,13 @@ class ClientContext {
/// Applications never need to call this method.
grpc_call* c_call() { return call_; }
+ /// EXPERIMENTAL debugging API
+ ///
+ /// if status is not ok() for an RPC, this will return a detailed string
+ /// of the gRPC Core error that led to the failure. It should not be relied
+ /// upon for anything other than gaining more debug data in failure cases.
+ grpc::string debug_error_string() const { return debug_error_string_; }
+
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);
@@ -374,6 +381,11 @@ class ClientContext {
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
+ // Used by friend class CallOpClientRecvStatus
+ void set_debug_error_string(const grpc::string& debug_error_string) {
+ debug_error_string_ = debug_error_string;
+ }
+
grpc_call* call() const { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
@@ -412,6 +424,8 @@ class ClientContext {
grpc_compression_algorithm compression_algorithm_;
bool initial_metadata_corked_;
+
+ grpc::string debug_error_string_;
};
} // namespace grpc