/** Extracts the GRPC status code if available. Returns UNKNOWN for non-GRPC exceptions. */ private static Status getStatus(Throwable throwable) { Status status = Status.UNKNOWN; if (throwable instanceof StatusRuntimeException) { status = ((StatusRuntimeException) throwable).getStatus(); } else if (throwable instanceof StatusException) { status = ((StatusException) throwable).getStatus(); } return status; }
private static void assertResponseTimeoutExceptionOrDeadlineExceeded(@Nullable Throwable cause) { assertThat(cause).isNotNull(); // Both exceptions can be raised when a timeout occurs due to timing issues, // and the first triggered one wins. if (cause instanceof ResponseTimeoutException) { return; } if (cause instanceof StatusException) { assertThat(((StatusException) cause).getStatus().getCode()).isEqualTo(Code.DEADLINE_EXCEEDED); return; } fail("cause must be a ResponseTimeoutException or a StatusException: ", cause); }
private static void checkRequestLogStatus(RequestLogStatusChecker checker) throws Exception { final RequestLog log = requestLogQueue.take(); assertThat(log.availabilities()).contains(RequestLogAvailability.COMPLETE); final RpcRequest rpcReq = (RpcRequest) log.requestContent(); final RpcResponse rpcRes = (RpcResponse) log.responseContent(); assertThat(rpcReq).isNull(); assertThat((Object) rpcRes).isNotNull(); assertThat(rpcRes.cause()).isNotNull(); checker.check(((StatusException) rpcRes.cause()).getStatus()); }
private void checkRequestLog(RequestLogChecker checker) throws Exception { final RequestLog log = requestLogQueue.take(); assertThat(log.availabilities()).contains(RequestLogAvailability.COMPLETE); final RpcRequest rpcReq = (RpcRequest) log.requestContent(); final RpcResponse rpcRes = (RpcResponse) log.responseContent(); assertThat(rpcReq).isNotNull(); assertThat((Object) rpcRes).isNotNull(); assertThat(rpcReq.serviceType()).isEqualTo(GrpcLogUtil.class); final Status grpcStatus; if (rpcRes.cause() != null) { grpcStatus = ((StatusException) rpcRes.cause()).getStatus(); } else { grpcStatus = null; } checker.check(rpcReq, rpcRes, grpcStatus); }
private static void checkRequestLog(RequestLogChecker checker) throws Exception { final RequestLog log = requestLogQueue.take(); assertThat(log.availabilities()).contains(RequestLogAvailability.COMPLETE); final RpcRequest rpcReq = (RpcRequest) log.requestContent(); final RpcResponse rpcRes = (RpcResponse) log.responseContent(); assertThat(rpcReq).isNotNull(); assertThat((Object) rpcRes).isNotNull(); assertThat(rpcReq.serviceType()).isEqualTo(GrpcLogUtil.class); final Status grpcStatus; if (rpcRes.cause() != null) { grpcStatus = ((StatusException) rpcRes.cause()).getStatus(); } else { grpcStatus = null; } checker.check(rpcReq, rpcRes, grpcStatus); }
@Test public void cancelAfterBegin() throws Exception { final StreamRecorder<StreamingInputCallResponse> responseObserver = StreamRecorder.create(); final StreamObserver<StreamingInputCallRequest> requestObserver = asyncStub.streamingInputCall(responseObserver); requestObserver.onError(new RuntimeException()); responseObserver.awaitCompletion(); assertThat(responseObserver.getValues()).isEmpty(); assertThat(Status.fromThrowable(responseObserver.getError()).getCode()).isEqualTo(Code.CANCELLED); final RequestLog log = requestLogQueue.take(); assertThat(log.availabilities()).contains(RequestLogAvailability.COMPLETE); assertThat(log.responseContent()).isInstanceOf(RpcResponse.class); final Throwable cause = ((RpcResponse) log.responseContent()).cause(); assertThat(cause).isInstanceOf(StatusException.class); assertThat(((StatusException) cause).getStatus().getCode()).isEqualTo(Code.CANCELLED); }
/** Extracts the GRPC status code if available. Returns UNKNOWN for non-GRPC exceptions. */ private static Status getStatus(Throwable throwable) { Status status = Status.UNKNOWN; if (throwable instanceof StatusRuntimeException) { status = ((StatusRuntimeException) throwable).getStatus(); } else if (throwable instanceof StatusException) { status = ((StatusException) throwable).getStatus(); } return status; }
public static boolean isContainerNotFound(Throwable cause) { if (cause instanceof StatusRuntimeException) { return Status.NOT_FOUND == ((StatusRuntimeException) cause).getStatus(); } else if (cause instanceof StatusException) { return Status.NOT_FOUND == ((StatusException) cause).getStatus(); } else { return false; } }
public static void logConnectionError(Logger log, Throwable t) { if (t instanceof StatusRuntimeException) { log.info("Connection status: " + niceToString(((StatusRuntimeException) t).getStatus())); } else if (t instanceof StatusException) { log.info("Connection status: " + niceToString(((StatusException) t).getStatus())); } else { log.error("Error from stream: " + t.getMessage(), t); } }
/** * Extract an error {@link Status} from the causal chain of a {@link Throwable}. * If no status can be found, a status is created with {@link Code#UNKNOWN} as its code and * {@code t} as its cause. * * @return non-{@code null} status */ public static Status fromThrowable(Throwable t) { Throwable cause = checkNotNull(t, "t"); while (cause != null) { if (cause instanceof StatusException) { return ((StatusException) cause).getStatus(); } else if (cause instanceof StatusRuntimeException) { return ((StatusRuntimeException) cause).getStatus(); } cause = cause.getCause(); } // Couldn't find a cause with a Status return UNKNOWN.withCause(t); }
/** * Executes a function on a {@code StatusException} or a {@code StatusRuntimeException}, passing in the exception's * metadata and trailers. * * @param t a {@code StatusException} or a {@code StatusRuntimeException} * @param function the function to execute, given the exception's status and trailers * @param <T> the function's return type * * @throws IllegalArgumentException if {@code t} is not a {@code StatusException} or a {@code StatusRuntimeException} */ public static <T> T doWithStatus(Throwable t, BiFunction<Status, Metadata, T> function) { if (t instanceof StatusException) { return function.apply(((StatusException) t).getStatus(), ((StatusException) t).getTrailers()); } if (t instanceof StatusRuntimeException) { return function.apply(((StatusRuntimeException) t).getStatus(), ((StatusRuntimeException) t).getTrailers()); } throw new IllegalArgumentException("Throwable " + t.getClass().getSimpleName() + " is neither a " + "StatusException nor a StatusRuntimeException"); } }
private static void logExceptions(RetriesExhaustedWithDetailsException e) { System.out.println(e.getExhaustiveDescription()); Set<String> codes = new TreeSet<>(); Set<String> messages = new TreeSet<>(); for (Throwable e1 : e.getCauses()) { if (e1 instanceof StatusException) { StatusException statusException = (StatusException) e1; codes.add(statusException.getStatus().getCode().name()); messages.add(statusException.getMessage()); } } } }
/** * Executes a function on a {@code StatusException} or a {@code StatusRuntimeException}, passing in the exception's * metadata and trailers. * * @param t a {@code StatusException} or a {@code StatusRuntimeException} * @param function the function to execute, given the exception's status and trailers * @param <T> the function's return type * * @throws IllegalArgumentException if {@code t} is not a {@code StatusException} or a {@code StatusRuntimeException} */ public static <T> T doWithStatus(Throwable t, BiFunction<Status, Metadata, T> function) { if (t instanceof StatusException) { return function.apply(((StatusException) t).getStatus(), ((StatusException) t).getTrailers()); } if (t instanceof StatusRuntimeException) { return function.apply(((StatusRuntimeException) t).getStatus(), ((StatusRuntimeException) t).getTrailers()); } throw new IllegalArgumentException("Throwable " + t.getClass().getSimpleName() + " is neither a " + "StatusException nor a StatusRuntimeException"); } }
private static boolean shouldRetryOnException(Throwable cause) { if (cause instanceof StatusRuntimeException || cause instanceof StatusException) { Status status; if (cause instanceof StatusException) { status = ((StatusException) cause).getStatus(); } else { status = ((StatusRuntimeException) cause).getStatus(); } switch (status.getCode()) { case INVALID_ARGUMENT: case ALREADY_EXISTS: case PERMISSION_DENIED: case UNAUTHENTICATED: return false; default: return true; } } else if (cause instanceof RuntimeException) { return false; } else { return true; } }
/** * Extract an error {@link Status} from the causal chain of a {@link Throwable}. * If no status can be found, a status is created with {@link Code#UNKNOWN} as its code and * {@code t} as its cause. * * @return non-{@code null} status */ public static Status fromThrowable(Throwable t) { Throwable cause = checkNotNull(t, "t"); while (cause != null) { if (cause instanceof StatusException) { return ((StatusException) cause).getStatus(); } else if (cause instanceof StatusRuntimeException) { return ((StatusRuntimeException) cause).getStatus(); } cause = cause.getCause(); } // Couldn't find a cause with a Status return UNKNOWN.withCause(t); }
/** * Extract a {@link com.google.rpc.Status} instance from the causal chain of a {@link Throwable}. * * @return the extracted {@link com.google.rpc.Status} instance, or {@code null} if none exists. * @throws IllegalArgumentException if an embedded {@link com.google.rpc.Status} is found and its * code does not match the gRPC {@link Status} code. * @since 1.3.0 */ @Nullable public static com.google.rpc.Status fromThrowable(Throwable t) { Throwable cause = checkNotNull(t, "t"); while (cause != null) { if (cause instanceof StatusException) { StatusException e = (StatusException) cause; return fromStatusAndTrailers(e.getStatus(), e.getTrailers()); } else if (cause instanceof StatusRuntimeException) { StatusRuntimeException e = (StatusRuntimeException) cause; return fromStatusAndTrailers(e.getStatus(), e.getTrailers()); } cause = cause.getCause(); } return null; }
private void handleGrpcRequest(ChannelHandlerContext ctx, GrpcState state, int streamId) { if (state.size != state.buffer.readableBytes()) { sendResponse( ctx, streamId, Unpooled.EMPTY_BUFFER, Status.INTERNAL.withDescription(GRPC_MESSAGE_WRONG_SIZE)); return; } try { ByteBuf grpcResponseBuffer = makeResponseBuffer(state.buffer.nioBuffer()); sendResponse(ctx, streamId, grpcResponseBuffer, Status.OK); } catch (InvalidProtocolBufferException e) { sendResponse( ctx, streamId, Unpooled.EMPTY_BUFFER, Status.INTERNAL.withDescription(GRPC_MESSAGE_CANNOT_MAKE_RESPONSE)); } catch (StatusException e) { sendResponse(ctx, streamId, Unpooled.EMPTY_BUFFER, e.getStatus()); } }
ApiException create(Throwable throwable) { if (throwable instanceof StatusException) { StatusException e = (StatusException) throwable; return create(throwable, e.getStatus().getCode()); } else if (throwable instanceof StatusRuntimeException) { StatusRuntimeException e = (StatusRuntimeException) throwable; return create(throwable, e.getStatus().getCode()); } else if (throwable instanceof ApiException) { return (ApiException) throwable; } else { // Do not retry on unknown throwable, even when UNKNOWN is in retryableCodes return ApiExceptionFactory.createException( throwable, GrpcStatusCode.of(Status.Code.UNKNOWN), false); } }
ApiException create(Throwable throwable) { if (throwable instanceof StatusException) { StatusException e = (StatusException) throwable; return create(throwable, e.getStatus().getCode()); } else if (throwable instanceof StatusRuntimeException) { StatusRuntimeException e = (StatusRuntimeException) throwable; return create(throwable, e.getStatus().getCode()); } else if (throwable instanceof ApiException) { return (ApiException) throwable; } else { // Do not retry on unknown throwable, even when UNKNOWN is in retryableCodes return ApiExceptionFactory.createException( throwable, GrpcStatusCode.of(Status.Code.UNKNOWN), false); } }
/** * Wraps the given {@link Throwable} in a {@link StatusRuntimeException}. If it contains an * embedded {@link StatusException} or {@link StatusRuntimeException}, the returned exception will * contain the embedded trailers and status, with the given exception as the cause. Otherwise, an * exception will be generated from an {@link Status#UNKNOWN} status. */ private static StatusRuntimeException toStatusRuntimeException(Throwable t) { Throwable cause = checkNotNull(t, "t"); while (cause != null) { // If we have an embedded status, use it and replace the cause if (cause instanceof StatusException) { StatusException se = (StatusException) cause; return new StatusRuntimeException(se.getStatus(), se.getTrailers()); } else if (cause instanceof StatusRuntimeException) { StatusRuntimeException se = (StatusRuntimeException) cause; return new StatusRuntimeException(se.getStatus(), se.getTrailers()); } cause = cause.getCause(); } return Status.UNKNOWN.withDescription("unexpected exception").withCause(t) .asRuntimeException(); }