1 /* 2 * Copyright 2015 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc; 18 19 import javax.annotation.Nullable; 20 21 /** 22 * {@link Status} in RuntimeException form, for propagating Status information via exceptions. 23 * 24 * @see StatusException 25 */ 26 public class StatusRuntimeException extends RuntimeException { 27 28 private static final long serialVersionUID = 1950934672280720624L; 29 private final Status status; 30 private final Metadata trailers; 31 32 private final boolean fillInStackTrace; 33 34 /** 35 * Constructs the exception with both a status. See also {@link Status#asRuntimeException()}. 36 * 37 * @since 1.0.0 38 */ StatusRuntimeException(Status status)39 public StatusRuntimeException(Status status) { 40 this(status, null); 41 } 42 43 /** 44 * Constructs the exception with both a status and trailers. See also {@link 45 * Status#asRuntimeException(Metadata)}. 46 * 47 * @since 1.0.0 48 */ StatusRuntimeException(Status status, @Nullable Metadata trailers)49 public StatusRuntimeException(Status status, @Nullable Metadata trailers) { 50 this(status, trailers, /*fillInStackTrace=*/ true); 51 } 52 StatusRuntimeException(Status status, @Nullable Metadata trailers, boolean fillInStackTrace)53 StatusRuntimeException(Status status, @Nullable Metadata trailers, boolean fillInStackTrace) { 54 super(Status.formatThrowableMessage(status), status.getCause()); 55 this.status = status; 56 this.trailers = trailers; 57 this.fillInStackTrace = fillInStackTrace; 58 fillInStackTrace(); 59 } 60 61 @Override fillInStackTrace()62 public synchronized Throwable fillInStackTrace() { 63 // Let's observe final variables in two states! This works because Throwable will invoke this 64 // method before fillInStackTrace is set, thus doing nothing. After the constructor has set 65 // fillInStackTrace, this method will properly fill it in. Additionally, sub classes may call 66 // this normally, because fillInStackTrace will either be set, or this method will be 67 // overriden. 68 return fillInStackTrace ? super.fillInStackTrace() : this; 69 } 70 71 /** 72 * Returns the status code as a {@link Status} object. 73 * 74 * @since 1.0.0 75 */ getStatus()76 public final Status getStatus() { 77 return status; 78 } 79 80 /** 81 * Returns the received trailers. 82 * 83 * @since 1.0.0 84 */ 85 @Nullable getTrailers()86 public final Metadata getTrailers() { 87 return trailers; 88 } 89 } 90