internal void ResolveException(string summary, Exception ex, [NotNull] out Status?status, out Exception resolvedException) { if (ex is OperationCanceledException) { status = (CallTask.IsCompletedSuccessfully) ? CallTask.Result : new Status(StatusCode.Cancelled, string.Empty); resolvedException = Channel.ThrowOperationCanceledOnCancellation ? ex : CreateRpcException(status.Value); } else if (ex is RpcException rpcException) { status = rpcException.Status; resolvedException = CreateRpcException(status.Value); } else { var exceptionMessage = CommonGrpcProtocolHelpers.ConvertToRpcExceptionMessage(ex); var statusCode = GrpcProtocolHelpers.ResolveRpcExceptionStatusCode(ex); status = new Status(statusCode, summary + " " + exceptionMessage, ex); resolvedException = CreateRpcException(status.Value); } }
private bool IsCancellationOrDeadlineException(Exception ex) { // Don't log OperationCanceledException if deadline has exceeded // or the call has been canceled. if (ex is OperationCanceledException && _callTcs.Task.IsCompletedSuccessfully() && (_callTcs.Task.Result.StatusCode == StatusCode.DeadlineExceeded || _callTcs.Task.Result.StatusCode == StatusCode.Cancelled)) { return(true); } // Exception may specify RST_STREAM or abort code that resolves to cancellation. // If protocol error is cancellation and deadline has been exceeded then that // means the server canceled and the local deadline timer hasn't triggered. if (GrpcProtocolHelpers.ResolveRpcExceptionStatusCode(ex) == StatusCode.Cancelled) { return(true); } return(false); }
/// <summary> /// Resolve the specified exception to an end-user exception that will be thrown from the client. /// The resolved exception is normally a RpcException. Returns true when the resolved exception is changed. /// </summary> internal bool ResolveException(string summary, Exception ex, [NotNull] out Status?status, out Exception resolvedException) { if (ex is OperationCanceledException) { status = (CallTask.IsCompletedSuccessfully) ? CallTask.Result : new Status(StatusCode.Cancelled, string.Empty); if (!Channel.ThrowOperationCanceledOnCancellation) { resolvedException = CreateRpcException(status.Value); return(true); } } else if (ex is RpcException rpcException) { status = rpcException.Status; // If trailers have been set, and the RpcException isn't using them, then // create new RpcException with trailers. Want to try and avoid this as // the exact stack location will be lost. // // Trailers could be set in another thread so copy to local variable. var trailers = Trailers; if (trailers != null && rpcException.Trailers != trailers) { resolvedException = CreateRpcException(status.Value); return(true); } } else { var exceptionMessage = CommonGrpcProtocolHelpers.ConvertToRpcExceptionMessage(ex); var statusCode = GrpcProtocolHelpers.ResolveRpcExceptionStatusCode(ex); status = new Status(statusCode, summary + " " + exceptionMessage, ex); resolvedException = CreateRpcException(status.Value); return(true); } resolvedException = ex; return(false); }