Skip to content

Commit 6cd3cf6

Browse files
Correctly expose all Databricks error detail types in DatabricksError. (#500)
## What changes are proposed in this pull request? This PR makes `ErrorDetails` accessible in `DatabricksError`. This is done by replacing the list of `ErrorDetail` with `ErrorDetails`. The changes introduced in this PR are breaking for users who depended on the list of `ErrorDetail`. ## How is this tested? Unit and integration tests.
1 parent 1aaab52 commit 6cd3cf6

40 files changed

+244
-286
lines changed

NEXT_CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
### Bug Fixes
88

9+
- [Breaking] `DatabricksError` now correctly exposes all Databricks error details types. This change is a breaking change for users depending on the `ErrorDetail` class. The same information can be accessed from `ErrorDetails.errorInfo`.
10+
911
### Documentation
1012

1113
### Internal Changes
Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.databricks.sdk.core;
22

3-
import com.databricks.sdk.core.error.ErrorDetail;
4-
import java.util.Collections;
5-
import java.util.List;
6-
import java.util.stream.Collectors;
3+
import com.databricks.sdk.core.error.details.ErrorDetails;
74

85
/**
96
* The result of checking whether {@code ApiClient} should retry a request.
@@ -17,45 +14,35 @@ public class DatabricksError extends DatabricksException {
1714
private final Throwable cause;
1815
private final String errorCode;
1916
private final int statusCode;
20-
21-
private final List<ErrorDetail> details;
17+
private final ErrorDetails errorDetails;
2218

2319
public DatabricksError(int statusCode) {
24-
this("", "OK", statusCode, null, Collections.emptyList());
20+
this("", "OK", statusCode, null, ErrorDetails.builder().build());
2521
}
2622

2723
public DatabricksError(String errorCode, String message) {
28-
this(errorCode, message, 400, null, Collections.emptyList());
24+
this(errorCode, message, 400, null, ErrorDetails.builder().build());
2925
}
3026

3127
public DatabricksError(String errorCode, String message, int statusCode) {
32-
this(errorCode, message, statusCode, null, Collections.emptyList());
28+
this(errorCode, message, statusCode, null, ErrorDetails.builder().build());
3329
}
3430

3531
public DatabricksError(String errorCode, int statusCode, Throwable cause) {
36-
this(errorCode, cause.getMessage(), statusCode, cause, Collections.emptyList());
32+
this(errorCode, cause.getMessage(), statusCode, cause, ErrorDetails.builder().build());
3733
}
3834

39-
public DatabricksError(
40-
String errorCode, String message, int statusCode, List<ErrorDetail> details) {
35+
public DatabricksError(String errorCode, String message, int statusCode, ErrorDetails details) {
4136
this(errorCode, message, statusCode, null, details);
4237
}
4338

4439
private DatabricksError(
45-
String errorCode,
46-
String message,
47-
int statusCode,
48-
Throwable cause,
49-
List<ErrorDetail> details) {
40+
String errorCode, String message, int statusCode, Throwable cause, ErrorDetails details) {
5041
super(message, cause);
5142
this.errorCode = errorCode;
5243
this.cause = cause;
5344
this.statusCode = statusCode;
54-
this.details = details == null ? Collections.emptyList() : details;
55-
}
56-
57-
public List<ErrorDetail> getErrorInfo() {
58-
return this.getDetailsByType("type.googleapis.com/google.rpc.ErrorInfo");
45+
this.errorDetails = details == null ? ErrorDetails.builder().build() : details;
5946
}
6047

6148
public String getErrorCode() {
@@ -70,7 +57,7 @@ public Throwable getCause() {
7057
return cause;
7158
}
7259

73-
List<ErrorDetail> getDetailsByType(String type) {
74-
return this.details.stream().filter(e -> e.getType().equals(type)).collect(Collectors.toList());
60+
public ErrorDetails getErrorDetails() {
61+
return errorDetails;
7562
}
7663
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/AbstractErrorMapper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.databricks.sdk.core.error;
22

33
import com.databricks.sdk.core.DatabricksError;
4+
import com.databricks.sdk.core.error.details.ErrorDetails;
45
import com.databricks.sdk.core.http.Response;
56
import java.util.HashMap;
6-
import java.util.List;
77
import java.util.Map;
88
import org.slf4j.Logger;
99
import org.slf4j.LoggerFactory;
@@ -13,12 +13,12 @@ abstract class AbstractErrorMapper {
1313

1414
@FunctionalInterface
1515
protected interface ErrorCodeRule {
16-
DatabricksError create(String message, List<ErrorDetail> details);
16+
DatabricksError create(String message, ErrorDetails details);
1717
}
1818

1919
@FunctionalInterface
2020
protected interface StatusCodeRule {
21-
DatabricksError create(String errorCode, String message, List<ErrorDetail> details);
21+
DatabricksError create(String errorCode, String message, ErrorDetails details);
2222
}
2323

2424
public DatabricksError apply(Response resp, ApiErrorBody errorBody) {
@@ -35,7 +35,7 @@ public DatabricksError apply(Response resp, ApiErrorBody errorBody) {
3535
int code = resp.getStatusCode();
3636
String message = errorBody.getMessage();
3737
String errorCode = errorBody.getErrorCode();
38-
List<ErrorDetail> details = errorBody.getErrorDetails();
38+
ErrorDetails details = errorBody.getErrorDetails();
3939
if (errorCodeMapping.containsKey(errorCode)) {
4040
return errorCodeMapping.get(errorCode).create(message, details);
4141
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/ApiErrorBody.java

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
import com.databricks.sdk.core.error.details.ErrorDetails;
44
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
55
import com.fasterxml.jackson.annotation.JsonProperty;
6-
import java.util.Arrays;
7-
import java.util.Collections;
8-
import java.util.List;
96

107
/**
118
* The union of all JSON error responses from the Databricks APIs, not including HTML responses.
@@ -20,7 +17,7 @@ public class ApiErrorBody {
2017
private String scimStatus;
2118
private String scimType;
2219
private String api12Error;
23-
private List<ErrorDetail> errorDetails;
20+
private ErrorDetails errorDetails;
2421

2522
public ApiErrorBody() {}
2623

@@ -48,14 +45,14 @@ public ApiErrorBody(
4845
this.scimStatus = scimStatus;
4946
this.scimType = scimType;
5047
this.api12Error = api12Error;
51-
this.errorDetails = fromDetails(errorDetails);
48+
this.errorDetails = errorDetails;
5249
}
5350

54-
public List<ErrorDetail> getErrorDetails() {
51+
public ErrorDetails getErrorDetails() {
5552
return errorDetails;
5653
}
5754

58-
public void setErrorDetails(List<ErrorDetail> errorDetails) {
55+
public void setErrorDetails(ErrorDetails errorDetails) {
5956
this.errorDetails = errorDetails;
6057
}
6158

@@ -106,26 +103,4 @@ public String getApi12Error() {
106103
public void setApi12Error(String api12Error) {
107104
this.api12Error = api12Error;
108105
}
109-
110-
/**
111-
* Converts the error details to a list of ErrorDetail objects. This only supports the ErrorInfo
112-
* type.
113-
*
114-
* @param details The error details to convert.
115-
* @return A list of ErrorDetail objects.
116-
*/
117-
private static List<ErrorDetail> fromDetails(ErrorDetails details) {
118-
if (details == null) {
119-
return Collections.emptyList();
120-
}
121-
if (!details.errorInfo().isPresent()) {
122-
return Collections.emptyList();
123-
}
124-
return Arrays.asList(
125-
new ErrorDetail(
126-
"type.googleapis.com/google.rpc.ErrorInfo",
127-
details.errorInfo().get().reason(),
128-
details.errorInfo().get().domain(),
129-
details.errorInfo().get().metadata()));
130-
}
131106
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/ApiErrors.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
import com.databricks.sdk.core.DatabricksError;
44
import com.databricks.sdk.core.DatabricksException;
5+
import com.databricks.sdk.core.error.details.ErrorDetails;
56
import com.databricks.sdk.core.http.Response;
67
import com.fasterxml.jackson.databind.ObjectMapper;
78
import java.io.*;
89
import java.nio.charset.StandardCharsets;
9-
import java.util.Collections;
1010
import java.util.regex.Matcher;
1111
import java.util.regex.Pattern;
1212
import org.apache.commons.io.IOUtils;
@@ -52,7 +52,7 @@ private static ApiErrorBody readErrorFromResponse(Response response) {
5252
errorBody.setErrorCode("SCIM_" + errorBody.getScimStatus());
5353
}
5454
if (errorBody.getErrorDetails() == null) {
55-
errorBody.setErrorDetails(Collections.emptyList());
55+
errorBody.setErrorDetails(ErrorDetails.builder().build());
5656
}
5757
return errorBody;
5858
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/ErrorDetail.java

Lines changed: 0 additions & 64 deletions
This file was deleted.

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/ErrorOverride.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import com.databricks.sdk.core.DatabricksError;
44
import com.databricks.sdk.core.DatabricksException;
5+
import com.databricks.sdk.core.error.details.ErrorDetails;
56
import com.databricks.sdk.core.http.Response;
67
import java.lang.reflect.Constructor;
7-
import java.util.List;
88
import java.util.regex.Pattern;
99

1010
public class ErrorOverride<T extends DatabricksError> {
@@ -68,7 +68,7 @@ public T makeError(ApiErrorBody body) {
6868
// All errors have a 2-argument constructor for the message and the error body.
6969
if (parameterTypes.length == 2
7070
&& parameterTypes[0].equals(String.class)
71-
&& parameterTypes[1].equals(List.class)) {
71+
&& parameterTypes[1].equals(ErrorDetails.class)) {
7272
try {
7373
return (T) constructor.newInstance(body.getMessage(), body.getErrorDetails());
7474
} catch (Exception e) {

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/PrivateLinkInfo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.databricks.sdk.core.error;
22

33
import com.databricks.sdk.core.DatabricksEnvironment;
4+
import com.databricks.sdk.core.error.details.ErrorDetails;
45
import com.databricks.sdk.core.http.Response;
56
import com.databricks.sdk.core.utils.Cloud;
6-
import java.util.Collections;
77
import java.util.HashMap;
88
import java.util.Map;
99

@@ -61,6 +61,6 @@ static PrivateLinkValidationError createPrivateLinkValidationError(Response resp
6161
DatabricksEnvironment env =
6262
DatabricksEnvironment.getEnvironmentFromHostname(resp.getUrl().getHost());
6363
PrivateLinkInfo info = PRIVATE_LINK_INFOS.get(env.getCloud());
64-
return new PrivateLinkValidationError(info.errorMessage(), Collections.emptyList());
64+
return new PrivateLinkValidationError(info.errorMessage(), ErrorDetails.builder().build());
6565
}
6666
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.databricks.sdk.core.error;
22

3+
import com.databricks.sdk.core.error.details.ErrorDetails;
34
import com.databricks.sdk.core.error.platform.PermissionDenied;
4-
import java.util.List;
55

66
public class PrivateLinkValidationError extends PermissionDenied {
7-
public PrivateLinkValidationError(String message, List<ErrorDetail> details) {
7+
public PrivateLinkValidationError(String message, ErrorDetails details) {
88
super("PRIVATE_LINK_VALIDATION_ERROR", message, details);
99
}
1010
}

databricks-sdk-java/src/main/java/com/databricks/sdk/core/error/details/DebugInfo.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public abstract class DebugInfo {
7777
* @return a new builder instance
7878
*/
7979
public static Builder builder() {
80-
return new AutoValue_DebugInfo.Builder();
80+
return new AutoValue_DebugInfo.Builder().setStackEntries(Collections.emptyList());
8181
}
8282

8383
/** Builder for constructing DebugInfo instances. */
@@ -108,15 +108,6 @@ public abstract static class Builder {
108108
*
109109
* @return a new DebugInfo instance
110110
*/
111-
public DebugInfo build() {
112-
if (stackEntries() == null) {
113-
setStackEntries(Collections.emptyList());
114-
}
115-
return autoBuild();
116-
}
117-
118-
abstract List<String> stackEntries();
119-
120-
abstract DebugInfo autoBuild();
111+
public abstract DebugInfo build();
121112
}
122113
}

0 commit comments

Comments
 (0)