All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.grpc.protobuf.StatusProto Maven / Gradle / Ivy

There is a newer version: 1.69.0
Show newest version
/*
 * Copyright 2017 The gRPC Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.grpc.protobuf;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import io.grpc.ExperimentalApi;
import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.StatusException;
import io.grpc.StatusRuntimeException;
import io.grpc.protobuf.lite.ProtoLiteUtils;
import javax.annotation.Nullable;

/** Utility methods for working with {@link com.google.rpc.Status}. */
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4695")
public final class StatusProto {
  private StatusProto() {}

  private static final Metadata.Key STATUS_DETAILS_KEY =
      Metadata.Key.of(
          "grpc-status-details-bin",
          ProtoLiteUtils.metadataMarshaller(com.google.rpc.Status.getDefaultInstance()));

  /**
   * Convert a {@link com.google.rpc.Status} instance to a {@link StatusRuntimeException}.
   *
   * 

The returned {@link StatusRuntimeException} will wrap a {@link Status} whose code and * description are set from the code and message in {@code statusProto}. {@code statusProto} will * be serialized and placed into the metadata of the returned {@link StatusRuntimeException}. * * @throws IllegalArgumentException if the value of {@code statusProto.getCode()} is not a valid * gRPC status code. * @since 1.3.0 */ public static StatusRuntimeException toStatusRuntimeException(com.google.rpc.Status statusProto) { return toStatus(statusProto).asRuntimeException(toMetadata(statusProto)); } /** * Convert a {@link com.google.rpc.Status} instance to a {@link StatusRuntimeException} with * additional metadata. * *

The returned {@link StatusRuntimeException} will wrap a {@link Status} whose code and * description are set from the code and message in {@code statusProto}. {@code statusProto} will * be serialized and added to {@code metadata}. {@code metadata} will be set as the metadata of * the returned {@link StatusRuntimeException}. * * @throws IllegalArgumentException if the value of {@code statusProto.getCode()} is not a valid * gRPC status code. * @since 1.3.0 */ public static StatusRuntimeException toStatusRuntimeException( com.google.rpc.Status statusProto, Metadata metadata) { return toStatus(statusProto).asRuntimeException(toMetadata(statusProto, metadata)); } /** * Convert a {@link com.google.rpc.Status} instance to a {@link StatusException}. * *

The returned {@link StatusException} will wrap a {@link Status} whose code and description * are set from the code and message in {@code statusProto}. {@code statusProto} will be * serialized and placed into the metadata of the returned {@link StatusException}. * * @throws IllegalArgumentException if the value of {@code statusProto.getCode()} is not a valid * gRPC status code. * @since 1.3.0 */ public static StatusException toStatusException(com.google.rpc.Status statusProto) { return toStatus(statusProto).asException(toMetadata(statusProto)); } /** * Convert a {@link com.google.rpc.Status} instance to a {@link StatusException} with additional * metadata. * *

The returned {@link StatusException} will wrap a {@link Status} whose code and description * are set from the code and message in {@code statusProto}. {@code statusProto} will be * serialized and added to {@code metadata}. {@code metadata} will be set as the metadata of the * returned {@link StatusException}. * * @throws IllegalArgumentException if the value of {@code statusProto.getCode()} is not a valid * gRPC status code. * @since 1.3.0 */ public static StatusException toStatusException( com.google.rpc.Status statusProto, Metadata metadata) { return toStatus(statusProto).asException(toMetadata(statusProto, metadata)); } /** * Convert a {@link com.google.rpc.Status} instance to a {@link StatusException} with additional * metadata and the root exception thrown. The exception isn't propagated over the wire. * *

The returned {@link StatusException} will wrap a {@link Status} whose code and description * are set from the code and message in {@code statusProto}. {@code statusProto} will be * serialized and added to {@code metadata}. {@code metadata} will be set as the metadata of the * returned {@link StatusException}. The {@link Throwable} is the exception that is set as the * {@code cause} of the returned {@link StatusException}. * * @throws IllegalArgumentException if the value of {@code statusProto.getCode()} is not a valid * gRPC status code. * @since 1.3.0 */ public static StatusException toStatusException( com.google.rpc.Status statusProto, Metadata metadata, Throwable cause) { return toStatus(statusProto).withCause(cause).asException(toMetadata(statusProto, metadata)); } private static Status toStatus(com.google.rpc.Status statusProto) { Status status = Status.fromCodeValue(statusProto.getCode()); checkArgument(status.getCode().value() == statusProto.getCode(), "invalid status code"); return status.withDescription(statusProto.getMessage()); } private static Metadata toMetadata(com.google.rpc.Status statusProto) { Metadata metadata = new Metadata(); metadata.put(STATUS_DETAILS_KEY, statusProto); return metadata; } private static Metadata toMetadata(com.google.rpc.Status statusProto, Metadata metadata) { checkNotNull(metadata, "metadata must not be null"); metadata.discardAll(STATUS_DETAILS_KEY); metadata.put(STATUS_DETAILS_KEY, statusProto); return metadata; } /** * 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; } /** * Extracts the {@code google.rpc.Status} from trailers, and makes sure they match the gRPC * {@code status}. If the trailers do not contain a {@code google.rpc.Status}, it uses * {@code status} param to generate a {@code google.rpc.Status}. * * @return the embedded google.rpc.Status * @since 1.11.0 */ public static com.google.rpc.Status fromStatusAndTrailers( Status status, @Nullable Metadata trailers) { checkNotNull(status, "status"); if (trailers != null) { com.google.rpc.Status statusProto = trailers.get(STATUS_DETAILS_KEY); if (statusProto != null) { checkArgument( status.getCode().value() == statusProto.getCode(), "com.google.rpc.Status code must match gRPC status code"); return statusProto; } } // fall-back to status, this is useful if the error is local. e.g. Server is unavailable. com.google.rpc.Status.Builder statusBuilder = com.google.rpc.Status.newBuilder() .setCode(status.getCode().value()); if (status.getDescription() != null) { statusBuilder.setMessage(status.getDescription()); } return statusBuilder.build(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy