diff options
author | Noah Eisen <ncteisen@gmail.com> | 2017-11-21 07:35:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-21 07:35:32 -0800 |
commit | dd010f2297560edcfa863c90988020ade485f53a (patch) | |
tree | 4b464ba1969313b1e00920a7a61b17ec59938fe8 /src/core | |
parent | 39b0325dc7770b3325a3604b62120f1e9fed301e (diff) | |
parent | 11c1c47fe95e6ec8c9ff97d1e702561eee36434e (diff) |
Merge pull request #13364 from ncteisen/surfacing-error-details
Add Error String to Recv Status API
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 9 | ||||
-rw-r--r-- | src/core/lib/channel/channel_stack.h | 1 | ||||
-rw-r--r-- | src/core/lib/surface/call.cc | 34 | ||||
-rw-r--r-- | src/core/lib/transport/error_utils.cc | 9 | ||||
-rw-r--r-- | src/core/lib/transport/error_utils.h | 8 |
5 files changed, 38 insertions, 23 deletions
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 5bd647885f..01a16955d9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1758,7 +1758,7 @@ static void send_goaway(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_http2_error_code http_error; grpc_slice slice; grpc_error_get_status(exec_ctx, error, GRPC_MILLIS_INF_FUTURE, nullptr, - &slice, &http_error); + &slice, &http_error, nullptr); grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error, grpc_slice_ref_internal(slice), &t->qbuf); grpc_chttp2_initiate_write(exec_ctx, t, @@ -2061,7 +2061,7 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx* exec_ctx, if (s->id != 0) { grpc_http2_error_code http_error; grpc_error_get_status(exec_ctx, due_to_error, s->deadline, nullptr, - nullptr, &http_error); + nullptr, &http_error, nullptr); grpc_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error, &s->stats.outgoing)); @@ -2079,7 +2079,8 @@ void grpc_chttp2_fake_status(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_error* error) { grpc_status_code status; grpc_slice slice; - grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, nullptr); + grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, nullptr, + nullptr); if (status != GRPC_STATUS_OK) { s->seen_error = true; } @@ -2244,7 +2245,7 @@ static void close_from_api(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_status_code grpc_status; grpc_slice slice; grpc_error_get_status(exec_ctx, error, s->deadline, &grpc_status, &slice, - nullptr); + nullptr, nullptr); GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100); diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 6b41ad105a..830c1123d0 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -84,6 +84,7 @@ typedef struct { typedef struct { grpc_call_stats stats; grpc_status_code final_status; + const char** error_string; } grpc_call_final_info; /* Channel filters specify: diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index a83c95c8dc..a2eb02bd85 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -234,6 +234,7 @@ struct grpc_call { struct { grpc_status_code* status; grpc_slice* status_details; + const char** error_string; } client; struct { int* cancelled; @@ -284,7 +285,8 @@ static void receiving_slice_ready(grpc_exec_ctx* exec_ctx, void* bctlp, static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details); + void* set_value_user_data, grpc_slice* details, + const char** error_string); static void set_status_value_directly(grpc_status_code status, void* dest); static void set_status_from_error(grpc_exec_ctx* exec_ctx, grpc_call* call, status_source source, grpc_error* error); @@ -546,7 +548,8 @@ static void destroy_call(grpc_exec_ctx* exec_ctx, void* call, } get_final_status(exec_ctx, c, set_status_value_directly, - &c->final_info.final_status, nullptr); + &c->final_info.final_status, nullptr, + c->final_info.error_string); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); @@ -733,16 +736,15 @@ static void cancel_with_status(grpc_exec_ctx* exec_ctx, grpc_call* c, * FINAL STATUS CODE MANIPULATION */ -static bool get_final_status_from(grpc_exec_ctx* exec_ctx, grpc_call* call, - grpc_error* error, bool allow_ok_status, - void (*set_value)(grpc_status_code code, - void* user_data), - void* set_value_user_data, - grpc_slice* details) { +static bool get_final_status_from( + grpc_exec_ctx* exec_ctx, grpc_call* call, grpc_error* error, + bool allow_ok_status, + void (*set_value)(grpc_status_code code, void* user_data), + void* set_value_user_data, grpc_slice* details, const char** error_string) { grpc_status_code code; grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(exec_ctx, error, call->send_deadline, &code, &slice, - nullptr); + nullptr, error_string); if (code == GRPC_STATUS_OK && !allow_ok_status) { return false; } @@ -757,7 +759,8 @@ static bool get_final_status_from(grpc_exec_ctx* exec_ctx, grpc_call* call, static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details) { + void* set_value_user_data, grpc_slice* details, + const char** error_string) { int i; received_status status[STATUS_SOURCE_COUNT]; for (i = 0; i < STATUS_SOURCE_COUNT; i++) { @@ -781,7 +784,7 @@ static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, grpc_error_has_clear_grpc_status(status[i].error)) { if (get_final_status_from(exec_ctx, call, status[i].error, allow_ok_status != 0, set_value, - set_value_user_data, details)) { + set_value_user_data, details, error_string)) { return; } } @@ -791,7 +794,7 @@ static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, if (status[i].is_set) { if (get_final_status_from(exec_ctx, call, status[i].error, allow_ok_status != 0, set_value, - set_value_user_data, details)) { + set_value_user_data, details, error_string)) { return; } } @@ -1332,10 +1335,11 @@ static void post_batch_completion(grpc_exec_ctx* exec_ctx, if (call->is_client) { get_final_status(exec_ctx, call, set_status_value_directly, call->final_op.client.status, - call->final_op.client.status_details); + call->final_op.client.status_details, + call->final_op.client.error_string); } else { get_final_status(exec_ctx, call, set_cancelled_value, - call->final_op.server.cancelled, nullptr); + call->final_op.server.cancelled, nullptr, nullptr); } GRPC_ERROR_UNREF(error); @@ -1992,6 +1996,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx* exec_ctx, call->final_op.client.status = op->data.recv_status_on_client.status; call->final_op.client.status_details = op->data.recv_status_on_client.status_details; + call->final_op.client.error_string = + op->data.recv_status_on_client.error_string; stream_op->recv_trailing_metadata = true; stream_op->collect_stats = true; stream_op_payload->recv_trailing_metadata.recv_trailing_metadata = diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 19510b4c8d..69c8ae6de3 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -18,6 +18,7 @@ #include "src/core/lib/transport/error_utils.h" +#include <grpc/support/string_util.h> #include "src/core/lib/iomgr/error_internal.h" #include "src/core/lib/transport/status_conversion.h" @@ -41,8 +42,8 @@ static grpc_error* recursively_find_error_with_field(grpc_error* error, void grpc_error_get_status(grpc_exec_ctx* exec_ctx, grpc_error* error, grpc_millis deadline, grpc_status_code* code, - grpc_slice* slice, - grpc_http2_error_code* http_error) { + grpc_slice* slice, grpc_http2_error_code* http_error, + const char** error_string) { // Start with the parent error and recurse through the tree of children // until we find the first one that has a status code. grpc_error* found_error = @@ -69,6 +70,10 @@ void grpc_error_get_status(grpc_exec_ctx* exec_ctx, grpc_error* error, } if (code != nullptr) *code = status; + if (error_string != NULL && status != GRPC_STATUS_OK) { + *error_string = gpr_strdup(grpc_error_string(error)); + } + if (http_error != nullptr) { if (grpc_error_get_int(found_error, GRPC_ERROR_INT_HTTP2_ERROR, &integer)) { *http_error = (grpc_http2_error_code)integer; diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h index 690e42058a..6f21f484e5 100644 --- a/src/core/lib/transport/error_utils.h +++ b/src/core/lib/transport/error_utils.h @@ -30,13 +30,15 @@ extern "C" { /// A utility function to get the status code and message to be returned /// to the application. If not set in the top-level message, looks /// through child errors until it finds the first one with these attributes. -/// All attributes are pulled from the same child error. If any of the -/// attributes (code, msg, http_status) are unneeded, they can be passed as +/// All attributes are pulled from the same child error. error_string will +/// be populated with the entire error string. If any of the attributes (code, +/// msg, http_status, error_string) are unneeded, they can be passed as /// NULL. void grpc_error_get_status(grpc_exec_ctx* exec_ctx, grpc_error* error, grpc_millis deadline, grpc_status_code* code, grpc_slice* slice, - grpc_http2_error_code* http_status); + grpc_http2_error_code* http_status, + const char** error_string); /// A utility function to check whether there is a clear status code that /// doesn't need to be guessed in \a error. This means that \a error or some |