/** * Extract an error trailers from the causal chain of a {@link Throwable}. * * @return the trailers or {@code null} if not found. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4683") public static Metadata trailersFromThrowable(Throwable t) { Throwable cause = checkNotNull(t, "t"); while (cause != null) { if (cause instanceof StatusException) { return ((StatusException) cause).getTrailers(); } else if (cause instanceof StatusRuntimeException) { return ((StatusRuntimeException) cause).getTrailers(); } cause = cause.getCause(); } return null; }
/** * 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"); } }
/** * 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"); } }
/** * Extract an error trailers from the causal chain of a {@link Throwable}. * * @return the trailers or {@code null} if not found. */ @ExperimentalApi public static Metadata trailersFromThrowable(Throwable t) { Throwable cause = checkNotNull(t, "t"); while (cause != null) { if (cause instanceof StatusException) { return ((StatusException) cause).getTrailers(); } else if (cause instanceof StatusRuntimeException) { return ((StatusRuntimeException) cause).getTrailers(); } cause = cause.getCause(); } return null; }
/** * 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; }
/** * 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(); }