blob: 6b6de600f0df8b0a8f7fb5cd53dbe6831b8a9e9c [file] [log] [blame]
ejona07d3f6a2014-05-14 11:26:57 -07001package com.google.net.stubby;
2
3import com.google.common.base.Preconditions;
lryan2ce84462014-06-02 14:43:36 -07004import com.google.common.base.Throwables;
ejona07d3f6a2014-05-14 11:26:57 -07005import com.google.net.stubby.transport.Transport;
6
7import javax.annotation.Nullable;
8import javax.annotation.concurrent.Immutable;
9
10/**
11 * Defines the status of an operation using the canonical error space.
12 */
13@Immutable
14public class Status {
15
16 public static final Status OK = new Status(Transport.Code.OK);
nathanmittlercc7cdb12014-07-11 12:00:32 -070017 public static final Status CANCELLED = new Status(Transport.Code.CANCELLED);
ejona07d3f6a2014-05-14 11:26:57 -070018
lryan2ce84462014-06-02 14:43:36 -070019 public static Status fromThrowable(Throwable t) {
20 for (Throwable cause : Throwables.getCausalChain(t)) {
21 if (cause instanceof OperationException) {
22 return ((Status.OperationException) cause).getStatus();
23 } else if (cause instanceof OperationRuntimeException) {
24 return ((Status.OperationRuntimeException) cause).getStatus();
25 }
26 }
27 // Couldn't find a cause with a Status
28 return new Status(Transport.Code.INTERNAL, t);
29 }
30
ejona07d3f6a2014-05-14 11:26:57 -070031 private final Transport.Code code;
32 private final String description;
33 private final Throwable cause;
34
35 public Status(Transport.Code code) {
36 this(code, null, null);
37 }
38
39 public Status(Transport.Code code, @Nullable String description) {
40 this(code, description, null);
41 }
42
43 public Status(Transport.Code code, @Nullable Throwable cause) {
44 this(code, null, cause);
45 }
46
47 public Status(Transport.Code code, @Nullable String description, @Nullable Throwable cause) {
48 this.code = Preconditions.checkNotNull(code);
49 this.description = description;
50 this.cause = cause;
51 }
52
53 public Transport.Code getCode() {
54 return code;
55 }
56
57 @Nullable
58 public String getDescription() {
59 return description;
60 }
61
62 @Nullable
63 public Throwable getCause() {
64 return cause;
65 }
66
ejona35cabd02014-06-11 14:46:25 -070067 public boolean isOk() {
68 return OK.getCode() == getCode();
69 }
70
ejona07d3f6a2014-05-14 11:26:57 -070071 /**
72 * Override this status with another if allowed.
73 */
74 public Status overrideWith(Status newStatus) {
75 if (this.getCode() == Transport.Code.OK || newStatus.code == Transport.Code.OK) {
76 return this;
77 } else {
78 return newStatus;
79 }
80 }
81
82 public RuntimeException asRuntimeException() {
83 return new OperationRuntimeException(this);
84 }
85
86 public Exception asException() {
87 return new OperationException(this);
88 }
89
90 /**
91 * Exception thrown by implementations while managing an operation.
92 */
93 public static class OperationException extends Exception {
94
95 private final Status status;
96
97 public OperationException(Status status) {
zhangkune1ae25c2014-08-08 22:39:39 -070098 super(status.getCode() + ": " + status.getDescription(), status.getCause());
ejona07d3f6a2014-05-14 11:26:57 -070099 this.status = status;
100 }
101
102 public Status getStatus() {
103 return status;
104 }
105 }
106
107 /**
108 * Runtime exception thrown by implementations while managing an operation.
109 */
110 public static class OperationRuntimeException extends RuntimeException {
111
112 private final Status status;
113
114 public OperationRuntimeException(Status status) {
zhangkune1ae25c2014-08-08 22:39:39 -0700115 super(status.getCode() + ": " + status.getDescription(), status.getCause());
ejona07d3f6a2014-05-14 11:26:57 -0700116 this.status = status;
117 }
118
119 public Status getStatus() {
120 return status;
121 }
122 }
zhangkun347a22d2014-05-21 16:44:20 -0700123
124 @Override
125 public String toString() {
126 StringBuilder builder = new StringBuilder();
127 builder.append("[").append(code);
128 if (description != null) {
129 builder.append(";").append(description);
130 }
131 if (cause != null) {
132 builder.append(";").append(cause);
133 }
134 builder.append("]");
135 return builder.toString();
136 }
ejona07d3f6a2014-05-14 11:26:57 -0700137}