Skip to content

Commit 0a6c6f7

Browse files
committed
Chain cause exception to service exception in translateAndThrow (#946)
* Chain cause exception to service exception in translateAndThrow * Make exception constructors package scoped, better test coverage * Make exception classes final with public constructors
1 parent e213176 commit 0a6c6f7

11 files changed

Lines changed: 287 additions & 31 deletions

File tree

gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* @see <a href="https://cloud.google.com/bigquery/troubleshooting-errors">Google Cloud
3232
* BigQuery error codes</a>
3333
*/
34-
public class BigQueryException extends BaseServiceException {
34+
public final class BigQueryException extends BaseServiceException {
3535

3636
// see: https://cloud.google.com/bigquery/troubleshooting-errors
3737
private static final Set<Error> RETRYABLE_ERRORS = ImmutableSet.of(
@@ -44,7 +44,12 @@ public class BigQueryException extends BaseServiceException {
4444
private final BigQueryError error;
4545

4646
public BigQueryException(int code, String message) {
47-
this(code, message, null);
47+
this(code, message, (Throwable) null);
48+
}
49+
50+
public BigQueryException(int code, String message, Throwable cause) {
51+
super(code, message, null, true, cause);
52+
this.error = null;
4853
}
4954

5055
public BigQueryException(int code, String message, BigQueryError error) {
@@ -100,6 +105,6 @@ public int hashCode() {
100105
*/
101106
static BaseServiceException translateAndThrow(RetryHelperException ex) {
102107
BaseServiceException.translateAndPropagateIfPossible(ex);
103-
throw new BigQueryException(UNKNOWN_CODE, ex.getMessage());
108+
throw new BigQueryException(UNKNOWN_CODE, ex.getMessage(), ex.getCause());
104109
}
105110
}

gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static org.junit.Assert.assertEquals;
2424
import static org.junit.Assert.assertFalse;
2525
import static org.junit.Assert.assertNull;
26+
import static org.junit.Assert.assertSame;
2627
import static org.junit.Assert.assertTrue;
2728

2829
import com.google.cloud.BaseServiceException;
@@ -86,18 +87,29 @@ public void testBigqueryException() {
8687
assertTrue(exception.retryable());
8788
assertTrue(exception.idempotent());
8889

89-
IOException cause = new SocketTimeoutException();
90+
IOException cause = new SocketTimeoutException("socketTimeoutMessage");
9091
exception = new BigQueryException(cause);
92+
assertEquals(BigQueryException.UNKNOWN_CODE, exception.code());
9193
assertNull(exception.reason());
92-
assertNull(exception.getMessage());
94+
assertEquals("socketTimeoutMessage", exception.getMessage());
95+
assertEquals(cause, exception.getCause());
9396
assertTrue(exception.retryable());
9497
assertTrue(exception.idempotent());
95-
assertEquals(cause, exception.getCause());
98+
assertSame(cause, exception.getCause());
99+
100+
exception = new BigQueryException(504, "message", cause);
101+
assertEquals(504, exception.code());
102+
assertEquals("message", exception.getMessage());
103+
assertNull(exception.reason());
104+
assertNull(exception.error());
105+
assertTrue(exception.retryable());
106+
assertTrue(exception.idempotent());
107+
assertSame(cause, exception.getCause());
96108
}
97109

98110
@Test
99111
public void testTranslateAndThrow() throws Exception {
100-
BigQueryException cause = new BigQueryException(503, "message");
112+
Exception cause = new BigQueryException(503, "message");
101113
RetryHelperException exceptionMock = createMock(RetryHelperException.class);
102114
expect(exceptionMock.getCause()).andReturn(cause).times(2);
103115
replay(exceptionMock);
@@ -111,5 +123,21 @@ public void testTranslateAndThrow() throws Exception {
111123
} finally {
112124
verify(exceptionMock);
113125
}
126+
cause = new IllegalArgumentException("message");
127+
exceptionMock = createMock(RetryHelperException.class);
128+
expect(exceptionMock.getMessage()).andReturn("message").times(1);
129+
expect(exceptionMock.getCause()).andReturn(cause).times(2);
130+
replay(exceptionMock);
131+
try {
132+
BigQueryException.translateAndThrow(exceptionMock);
133+
} catch (BaseServiceException ex) {
134+
assertEquals(BigQueryException.UNKNOWN_CODE, ex.code());
135+
assertEquals("message", ex.getMessage());
136+
assertFalse(ex.retryable());
137+
assertTrue(ex.idempotent());
138+
assertSame(cause, ex.getCause());
139+
} finally {
140+
verify(exceptionMock);
141+
}
114142
}
115143
}

gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@
3030
* @see <a href="https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes">Google Cloud
3131
* Datastore error codes</a>
3232
*/
33-
public class DatastoreException extends BaseServiceException {
33+
public final class DatastoreException extends BaseServiceException {
3434

3535
// see https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes"
3636
private static final Set<Error> RETRYABLE_ERRORS = ImmutableSet.of(
3737
new Error(10, "ABORTED"), new Error(4, "DEADLINE_EXCEEDED"), new Error(14, "UNAVAILABLE"));
3838
private static final long serialVersionUID = 2663750991205874435L;
3939

40-
public DatastoreException(int code, String message, String reason, Throwable cause) {
41-
super(code, message, reason, true, cause);
40+
public DatastoreException(int code, String message, String reason) {
41+
this(code, message, reason, null);
4242
}
4343

44-
public DatastoreException(int code, String message, String reason) {
45-
super(code, message, reason, true);
44+
public DatastoreException(int code, String message, String reason, Throwable cause) {
45+
super(code, message, reason, true, cause);
4646
}
4747

4848
public DatastoreException(IOException exception) {
@@ -63,7 +63,7 @@ protected Set<Error> retryableErrors() {
6363
*/
6464
static DatastoreException translateAndThrow(RetryHelperException ex) {
6565
BaseServiceException.translateAndPropagateIfPossible(ex);
66-
throw new DatastoreException(UNKNOWN_CODE, ex.getMessage(), null);
66+
throw new DatastoreException(UNKNOWN_CODE, ex.getMessage(), null, ex.getCause());
6767
}
6868

6969
/**

gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static org.junit.Assert.assertEquals;
2424
import static org.junit.Assert.assertFalse;
2525
import static org.junit.Assert.assertNull;
26+
import static org.junit.Assert.assertSame;
2627
import static org.junit.Assert.assertTrue;
2728
import static org.junit.Assert.fail;
2829

@@ -66,18 +67,28 @@ public void testDatastoreException() throws Exception {
6667
assertFalse(exception.retryable());
6768
assertTrue(exception.idempotent());
6869

69-
IOException cause = new SocketTimeoutException();
70+
IOException cause = new SocketTimeoutException("socketTimeoutMessage");
7071
exception = new DatastoreException(cause);
72+
assertEquals(DatastoreException.UNKNOWN_CODE, exception.code());
7173
assertNull(exception.reason());
72-
assertNull(exception.getMessage());
74+
assertEquals("socketTimeoutMessage", exception.getMessage());
75+
assertEquals(cause, exception.getCause());
7376
assertTrue(exception.retryable());
7477
assertTrue(exception.idempotent());
78+
assertSame(cause, exception.getCause());
7579

80+
exception = new DatastoreException(2, "message", "INTERNAL", cause);
81+
assertEquals(2, exception.code());
82+
assertEquals("INTERNAL", exception.reason());
83+
assertEquals("message", exception.getMessage());
84+
assertFalse(exception.retryable());
85+
assertTrue(exception.idempotent());
86+
assertSame(cause, exception.getCause());
7687
}
7788

7889
@Test
7990
public void testTranslateAndThrow() throws Exception {
80-
DatastoreException cause = new DatastoreException(14, "message", "UNAVAILABLE");
91+
Exception cause = new DatastoreException(14, "message", "UNAVAILABLE");
8192
RetryHelper.RetryHelperException exceptionMock =
8293
createMock(RetryHelper.RetryHelperException.class);
8394
expect(exceptionMock.getCause()).andReturn(cause).times(2);
@@ -92,6 +103,22 @@ public void testTranslateAndThrow() throws Exception {
92103
} finally {
93104
verify(exceptionMock);
94105
}
106+
cause = new IllegalArgumentException("message");
107+
exceptionMock = createMock(RetryHelper.RetryHelperException.class);
108+
expect(exceptionMock.getMessage()).andReturn("message").times(1);
109+
expect(exceptionMock.getCause()).andReturn(cause).times(2);
110+
replay(exceptionMock);
111+
try {
112+
DatastoreException.translateAndThrow(exceptionMock);
113+
} catch (BaseServiceException ex) {
114+
assertEquals(DatastoreException.UNKNOWN_CODE, ex.code());
115+
assertEquals("message", ex.getMessage());
116+
assertFalse(ex.retryable());
117+
assertTrue(ex.idempotent());
118+
assertSame(cause, ex.getCause());
119+
} finally {
120+
verify(exceptionMock);
121+
}
95122
}
96123

97124
@Test

gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
/**
2929
* DNS service exception.
3030
*/
31-
public class DnsException extends BaseServiceException {
31+
public final class DnsException extends BaseServiceException {
3232

3333
// see: https://cloud.google.com/dns/troubleshooting
3434
private static final Set<Error> RETRYABLE_ERRORS = ImmutableSet.of(
@@ -48,8 +48,8 @@ public DnsException(GoogleJsonError error, boolean idempotent) {
4848
super(error, idempotent);
4949
}
5050

51-
private DnsException(int code, String message) {
52-
super(code, message, null, true);
51+
public DnsException(int code, String message, Throwable cause) {
52+
super(code, message, null, true, cause);
5353
}
5454

5555
@Override
@@ -66,6 +66,6 @@ protected Set<Error> retryableErrors() {
6666
*/
6767
static DnsException translateAndThrow(RetryHelperException ex) {
6868
BaseServiceException.translateAndPropagateIfPossible(ex);
69-
throw new DnsException(UNKNOWN_CODE, ex.getMessage());
69+
throw new DnsException(UNKNOWN_CODE, ex.getMessage(), ex.getCause());
7070
}
7171
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
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 com.google.cloud.dns;
18+
19+
import static org.easymock.EasyMock.createMock;
20+
import static org.easymock.EasyMock.expect;
21+
import static org.easymock.EasyMock.replay;
22+
import static org.easymock.EasyMock.verify;
23+
import static org.junit.Assert.assertEquals;
24+
import static org.junit.Assert.assertFalse;
25+
import static org.junit.Assert.assertNull;
26+
import static org.junit.Assert.assertSame;
27+
import static org.junit.Assert.assertTrue;
28+
29+
import com.google.api.client.googleapis.json.GoogleJsonError;
30+
import com.google.cloud.BaseServiceException;
31+
import com.google.cloud.RetryHelper.RetryHelperException;
32+
33+
import org.junit.Test;
34+
35+
import java.io.IOException;
36+
import java.net.SocketTimeoutException;
37+
38+
public class DnsExceptionTest {
39+
40+
@Test
41+
public void testDnsException() throws Exception {
42+
IOException cause = new SocketTimeoutException("socketTimeoutMessage");
43+
DnsException exception = new DnsException(500, "message", cause);
44+
assertEquals(500, exception.code());
45+
assertEquals("message", exception.getMessage());
46+
assertNull(exception.reason());
47+
assertTrue(exception.retryable());
48+
assertTrue(exception.idempotent());
49+
assertSame(cause, exception.getCause());
50+
51+
exception = new DnsException(502, "message", cause);
52+
assertEquals(502, exception.code());
53+
assertEquals("message", exception.getMessage());
54+
assertNull(exception.reason());
55+
assertTrue(exception.retryable());
56+
assertTrue(exception.idempotent());
57+
assertSame(cause, exception.getCause());
58+
59+
exception = new DnsException(503, "message", cause);
60+
assertEquals(503, exception.code());
61+
assertEquals("message", exception.getMessage());
62+
assertNull(exception.reason());
63+
assertTrue(exception.retryable());
64+
assertTrue(exception.idempotent());
65+
assertSame(cause, exception.getCause());
66+
67+
exception = new DnsException(429, "message", cause);
68+
assertEquals(429, exception.code());
69+
assertEquals("message", exception.getMessage());
70+
assertNull(exception.reason());
71+
assertTrue(exception.retryable());
72+
assertTrue(exception.idempotent());
73+
assertSame(cause, exception.getCause());
74+
75+
exception = new DnsException(404, "message", cause);
76+
assertEquals(404, exception.code());
77+
assertEquals("message", exception.getMessage());
78+
assertNull(exception.reason());
79+
assertFalse(exception.retryable());
80+
assertTrue(exception.idempotent());
81+
assertSame(cause, exception.getCause());
82+
83+
exception = new DnsException(cause, true);
84+
assertEquals(DnsException.UNKNOWN_CODE, exception.code());
85+
assertNull(exception.reason());
86+
assertEquals("socketTimeoutMessage", exception.getMessage());
87+
assertEquals(cause, exception.getCause());
88+
assertTrue(exception.retryable());
89+
assertTrue(exception.idempotent());
90+
assertSame(cause, exception.getCause());
91+
92+
GoogleJsonError error = new GoogleJsonError();
93+
error.setCode(503);
94+
error.setMessage("message");
95+
exception = new DnsException(error, true);
96+
assertEquals(503, exception.code());
97+
assertEquals("message", exception.getMessage());
98+
assertTrue(exception.retryable());
99+
assertTrue(exception.idempotent());
100+
}
101+
102+
@Test
103+
public void testTranslateAndThrow() throws Exception {
104+
IOException timeoutException = new SocketTimeoutException("message");
105+
Exception cause = new DnsException(timeoutException, true);
106+
RetryHelperException exceptionMock = createMock(RetryHelperException.class);
107+
expect(exceptionMock.getCause()).andReturn(cause).times(2);
108+
replay(exceptionMock);
109+
try {
110+
DnsException.translateAndThrow(exceptionMock);
111+
} catch (BaseServiceException ex) {
112+
assertEquals(DnsException.UNKNOWN_CODE, ex.code());
113+
assertNull(ex.reason());
114+
assertEquals("message", ex.getMessage());
115+
assertEquals(timeoutException, ex.getCause());
116+
assertTrue(ex.retryable());
117+
assertTrue(ex.idempotent());
118+
} finally {
119+
verify(exceptionMock);
120+
}
121+
cause = new IllegalArgumentException("message");
122+
exceptionMock = createMock(RetryHelperException.class);
123+
expect(exceptionMock.getMessage()).andReturn("message").times(1);
124+
expect(exceptionMock.getCause()).andReturn(cause).times(2);
125+
replay(exceptionMock);
126+
try {
127+
DnsException.translateAndThrow(exceptionMock);
128+
} catch (BaseServiceException ex) {
129+
assertEquals(DnsException.UNKNOWN_CODE, ex.code());
130+
assertEquals("message", ex.getMessage());
131+
assertFalse(ex.retryable());
132+
assertTrue(ex.idempotent());
133+
assertSame(cause, ex.getCause());
134+
} finally {
135+
verify(exceptionMock);
136+
}
137+
}
138+
}

gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public class ZoneTest {
6464
ChangeRequestInfo.builder().generatedId("someid").build();
6565
private static final ChangeRequestInfo CHANGE_REQUEST_NO_ID =
6666
ChangeRequestInfo.builder().build();
67-
private static final DnsException EXCEPTION = createStrictMock(DnsException.class);
67+
private static final DnsException EXCEPTION = new DnsException(-1, "message", null);
6868
private static final DnsOptions OPTIONS = createStrictMock(DnsOptions.class);
6969

7070
private Dns dns;

gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* @see <a href="https://cloud.google.com/resource-manager/v1/errors/core_errors">Google Cloud
3131
* Resource Manager error codes</a>
3232
*/
33-
public class ResourceManagerException extends BaseServiceException {
33+
public final class ResourceManagerException extends BaseServiceException {
3434

3535
// see https://cloud.google.com/resource-manager/v1/errors/core_errors
3636
private static final Set<Error> RETRYABLE_ERRORS = ImmutableSet.of(
@@ -48,7 +48,11 @@ public class ResourceManagerException extends BaseServiceException {
4848
private static final long serialVersionUID = -9207194488966554136L;
4949

5050
public ResourceManagerException(int code, String message) {
51-
super(code, message, null, true);
51+
this(code, message, null);
52+
}
53+
54+
public ResourceManagerException(int code, String message, Throwable cause) {
55+
super(code, message, null, true, cause);
5256
}
5357

5458
public ResourceManagerException(IOException exception) {
@@ -70,6 +74,6 @@ protected Set<Error> retryableErrors() {
7074
*/
7175
static ResourceManagerException translateAndThrow(RetryHelperException ex) {
7276
BaseServiceException.translateAndPropagateIfPossible(ex);
73-
throw new ResourceManagerException(UNKNOWN_CODE, ex.getMessage());
77+
throw new ResourceManagerException(UNKNOWN_CODE, ex.getMessage(), ex.getCause());
7478
}
7579
}

0 commit comments

Comments
 (0)