Skip to content

Commit 00c4bc1

Browse files
Update ApiErrorBody
1 parent 4f9fadf commit 00c4bc1

6 files changed

Lines changed: 205 additions & 165 deletions

File tree

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
@@ -28,14 +28,14 @@ public DatabricksError apply(Response resp, ApiErrorBody errorBody) {
2828
"Overriding error with {} (original status code: {}, original error code: {})",
2929
override.getDebugName(),
3030
resp.getStatusCode(),
31-
errorBody.getErrorCode());
31+
errorBody.errorCode());
3232
return override.makeError(errorBody);
3333
}
3434
}
3535
int code = resp.getStatusCode();
36-
String message = errorBody.getMessage();
37-
String errorCode = errorBody.getErrorCode();
38-
List<ErrorDetail> details = errorBody.getErrorDetails();
36+
String message = errorBody.message();
37+
String errorCode = errorBody.errorCode();
38+
List<ErrorDetail> details = errorBody.getErrorDetailsList();
3939
if (errorCodeMapping.containsKey(errorCode)) {
4040
return errorCodeMapping.get(errorCode).create(message, details);
4141
}
Lines changed: 138 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,160 @@
11
package com.databricks.sdk.core.error;
22

33
import com.databricks.sdk.core.error.details.ErrorDetails;
4+
import com.databricks.sdk.core.error.details.ErrorInfo;
45
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
56
import com.fasterxml.jackson.annotation.JsonProperty;
6-
import java.util.Arrays;
7+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
8+
import com.google.auto.value.AutoValue;
79
import java.util.Collections;
810
import java.util.List;
11+
import javax.annotation.Nullable;
912

1013
/**
1114
* The union of all JSON error responses from the Databricks APIs, not including HTML responses.
1215
*
1316
* <p>Unknown properties in the response should be ignored.
1417
*/
18+
@AutoValue
19+
@JsonDeserialize(builder = AutoValue_ApiErrorBody.Builder.class)
1520
@JsonIgnoreProperties(ignoreUnknown = true)
16-
public class ApiErrorBody {
17-
private String errorCode;
18-
private String message;
19-
private String scimDetail;
20-
private String scimStatus;
21-
private String scimType;
22-
private String api12Error;
23-
private List<ErrorDetail> errorDetails;
24-
25-
public ApiErrorBody() {}
26-
27-
public ApiErrorBody(
28-
@JsonProperty("error_code") String errorCode,
29-
@JsonProperty("message") String message,
30-
@JsonProperty("detail") String scimDetail,
31-
@JsonProperty("status") String scimStatus,
32-
@JsonProperty("scimType") String scimType,
33-
@JsonProperty("error") String api12Error,
34-
@JsonProperty("details") ErrorDetails errorDetails) {
35-
this.errorCode = errorCode;
36-
this.message = message;
37-
this.scimDetail = scimDetail;
38-
this.scimStatus = scimStatus;
39-
this.scimType = scimType;
40-
this.api12Error = api12Error;
41-
this.errorDetails = fromDetails(errorDetails);
42-
}
43-
44-
public List<ErrorDetail> getErrorDetails() {
45-
return errorDetails;
46-
}
47-
48-
public void setErrorDetails(List<ErrorDetail> errorDetails) {
49-
this.errorDetails = errorDetails;
50-
}
51-
52-
public String getErrorCode() {
53-
return errorCode;
54-
}
55-
56-
public void setErrorCode(String errorCode) {
57-
this.errorCode = errorCode;
58-
}
59-
60-
public String getMessage() {
61-
return message;
62-
}
63-
64-
public void setMessage(String message) {
65-
this.message = message;
66-
}
67-
68-
public String getScimDetail() {
69-
return scimDetail;
70-
}
71-
72-
public void setScimDetail(String scimDetail) {
73-
this.scimDetail = scimDetail;
74-
}
75-
76-
public String getScimStatus() {
77-
return scimStatus;
78-
}
79-
80-
public void setScimStatus(String scimStatus) {
81-
this.scimStatus = scimStatus;
82-
}
83-
84-
public String getScimType() {
85-
return scimType;
86-
}
87-
88-
public void setScimType(String scimType) {
89-
this.scimType = scimType;
90-
}
91-
92-
public String getApi12Error() {
93-
return api12Error;
94-
}
95-
96-
public void setApi12Error(String api12Error) {
97-
this.api12Error = api12Error;
98-
}
99-
100-
private static List<ErrorDetail> fromDetails(ErrorDetails details) {
101-
if (details == null) {
21+
public abstract class ApiErrorBody {
22+
23+
@JsonProperty("error_code")
24+
@Nullable public abstract String errorCode();
25+
26+
@JsonProperty("message")
27+
@Nullable public abstract String message();
28+
29+
@JsonProperty("detail")
30+
@Nullable public abstract String scimDetail();
31+
32+
@JsonProperty("status")
33+
@Nullable public abstract String scimStatus();
34+
35+
@JsonProperty("scimType")
36+
@Nullable public abstract String scimType();
37+
38+
@JsonProperty("error")
39+
@Nullable public abstract String api12Error();
40+
41+
@JsonProperty("details")
42+
@Nullable public abstract ErrorDetails errorDetails();
43+
44+
/**
45+
* Returns a builder for constructing ApiErrorBody instances with the same values as this
46+
* instance.
47+
*
48+
* @return a new builder instance
49+
*/
50+
public abstract Builder toBuilder();
51+
52+
/**
53+
* Creates a new builder for constructing ApiErrorBody instances.
54+
*
55+
* @return a new builder instance
56+
*/
57+
public static Builder builder() {
58+
return new AutoValue_ApiErrorBody.Builder();
59+
}
60+
61+
/**
62+
* Converts ErrorDetails to a List of legacy ErrorDetail objects for backward compatibility. This
63+
* method extracts the structured error information and converts it to the format expected by
64+
* legacy error handling code.
65+
*
66+
* @return a list of ErrorDetail objects, or an empty list if errorDetails() is null
67+
*/
68+
public List<ErrorDetail> getErrorDetailsList() {
69+
if (errorDetails() == null) {
10270
return Collections.emptyList();
10371
}
104-
if (!details.errorInfo().isPresent()) {
72+
if (!errorDetails().errorInfo().isPresent()) {
10573
return Collections.emptyList();
10674
}
107-
return Arrays.asList(
75+
76+
ErrorInfo errorInfo = errorDetails().errorInfo().get();
77+
return Collections.singletonList(
10878
new ErrorDetail(
10979
"type.googleapis.com/google.rpc.ErrorInfo",
110-
details.errorInfo().get().reason(),
111-
details.errorInfo().get().domain(),
112-
details.errorInfo().get().metadata()));
80+
errorInfo.reason(),
81+
errorInfo.domain(),
82+
errorInfo.metadata()));
83+
}
84+
85+
/** Builder for constructing ApiErrorBody instances. */
86+
@AutoValue.Builder
87+
@JsonIgnoreProperties(ignoreUnknown = true)
88+
public abstract static class Builder {
89+
90+
/**
91+
* Sets the error code.
92+
*
93+
* @param errorCode the error code
94+
* @return this builder for method chaining
95+
*/
96+
@JsonProperty("error_code")
97+
public abstract Builder setErrorCode(@Nullable String errorCode);
98+
99+
/**
100+
* Sets the message.
101+
*
102+
* @param message the message
103+
* @return this builder for method chaining
104+
*/
105+
@JsonProperty("message")
106+
public abstract Builder setMessage(@Nullable String message);
107+
108+
/**
109+
* Sets the SCIM detail.
110+
*
111+
* @param scimDetail the SCIM detail
112+
* @return this builder for method chaining
113+
*/
114+
@JsonProperty("detail")
115+
public abstract Builder setScimDetail(@Nullable String scimDetail);
116+
117+
/**
118+
* Sets the SCIM status.
119+
*
120+
* @param scimStatus the SCIM status
121+
* @return this builder for method chaining
122+
*/
123+
@JsonProperty("status")
124+
public abstract Builder setScimStatus(@Nullable String scimStatus);
125+
126+
/**
127+
* Sets the SCIM type.
128+
*
129+
* @param scimType the SCIM type
130+
* @return this builder for method chaining
131+
*/
132+
@JsonProperty("scimType")
133+
public abstract Builder setScimType(@Nullable String scimType);
134+
135+
/**
136+
* Sets the API 1.2 error.
137+
*
138+
* @param api12Error the API 1.2 error
139+
* @return this builder for method chaining
140+
*/
141+
@JsonProperty("error")
142+
public abstract Builder setApi12Error(@Nullable String api12Error);
143+
144+
/**
145+
* Sets the error details.
146+
*
147+
* @param errorDetails the error details
148+
* @return this builder for method chaining
149+
*/
150+
@JsonProperty("details")
151+
public abstract Builder setErrorDetails(@Nullable ErrorDetails errorDetails);
152+
153+
/**
154+
* Builds the ApiErrorBody instance.
155+
*
156+
* @return a new ApiErrorBody instance
157+
*/
158+
public abstract ApiErrorBody build();
113159
}
114160
}

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

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.fasterxml.jackson.databind.ObjectMapper;
77
import java.io.*;
88
import java.nio.charset.StandardCharsets;
9-
import java.util.Collections;
109
import java.util.regex.Matcher;
1110
import java.util.regex.Pattern;
1211
import org.apache.commons.io.IOUtils;
@@ -32,29 +31,34 @@ public static DatabricksError getDatabricksError(Response out, Exception error)
3231
private static ApiErrorBody readErrorFromResponse(Response response) {
3332
// Private link error handling depends purely on the response URL.
3433
if (PrivateLinkInfo.isPrivateLinkRedirect(response)) {
35-
return new ApiErrorBody();
34+
return ApiErrorBody.builder().build();
3635
}
3736
ApiErrorBody errorBody = parseApiError(response);
3837

3938
// Condense API v1.2 and SCIM error string and code into the message and errorCode fields of
4039
// DatabricksApiException.
41-
if (errorBody.getApi12Error() != null && !errorBody.getApi12Error().isEmpty()) {
42-
errorBody.setMessage(errorBody.getApi12Error());
40+
ApiErrorBody.Builder errorBodyBuilder = errorBody.toBuilder();
41+
42+
if (errorBody.api12Error() != null && !errorBody.api12Error().isEmpty()) {
43+
errorBodyBuilder.setMessage(errorBody.api12Error());
4344
}
44-
if (errorBody.getMessage() == null || errorBody.getMessage().isEmpty()) {
45-
if (errorBody.getScimDetail() != null && !"null".equals(errorBody.getScimDetail())) {
46-
errorBody.setMessage(errorBody.getScimDetail());
45+
if (errorBody.message() == null || errorBody.message().isEmpty()) {
46+
String scimMessage;
47+
if (errorBody.scimDetail() != null && !"null".equals(errorBody.scimDetail())) {
48+
scimMessage = errorBody.scimDetail();
4749
} else {
48-
errorBody.setMessage("SCIM API Internal Error");
50+
scimMessage = "SCIM API Internal Error";
4951
}
50-
String message = errorBody.getScimType() + " " + errorBody.getMessage();
51-
errorBody.setMessage(message.trim());
52-
errorBody.setErrorCode("SCIM_" + errorBody.getScimStatus());
52+
String message = errorBody.scimType() + " " + scimMessage;
53+
errorBodyBuilder.setMessage(message.trim());
54+
errorBodyBuilder.setErrorCode("SCIM_" + errorBody.scimStatus());
5355
}
54-
if (errorBody.getErrorDetails() == null) {
55-
errorBody.setErrorDetails(Collections.emptyList());
56+
if (errorBody.errorDetails() == null) {
57+
// Note: This appears to be a bug in the original code - errorDetails is not a List
58+
// We'll set it to null for now and this should be addressed separately
59+
errorBodyBuilder.setErrorDetails(null);
5660
}
57-
return errorBody;
61+
return errorBodyBuilder.build();
5862
}
5963

6064
/**
@@ -66,10 +70,9 @@ private static ApiErrorBody parseApiError(Response response) {
6670
try {
6771
InputStream in = response.getBody();
6872
if (in == null) {
69-
ApiErrorBody errorBody = new ApiErrorBody();
70-
errorBody.setMessage(
71-
String.format("Status response from server: %s", response.getStatus()));
72-
return errorBody;
73+
return ApiErrorBody.builder()
74+
.setMessage(String.format("Status response from server: %s", response.getStatus()))
75+
.build();
7376
}
7477

7578
// Read the body now, so we can try to parse as JSON and then fallback to old error handling
@@ -86,23 +89,23 @@ private static ApiErrorBody parseApiError(Response response) {
8689
}
8790

8891
private static ApiErrorBody parseUnknownError(Response response, String body, IOException err) {
89-
ApiErrorBody errorBody = new ApiErrorBody();
92+
ApiErrorBody.Builder errorBodyBuilder = ApiErrorBody.builder();
9093
String[] statusParts = response.getStatus().split(" ", 2);
9194
if (statusParts.length < 2) {
92-
errorBody.setErrorCode("UNKNOWN");
95+
errorBodyBuilder.setErrorCode("UNKNOWN");
9396
} else {
9497
String errorCode = statusParts[1].replaceAll("^[ .]+|[ .]+$", "");
95-
errorBody.setErrorCode(errorCode.replaceAll(" ", "_").toUpperCase());
98+
errorBodyBuilder.setErrorCode(errorCode.replaceAll(" ", "_").toUpperCase());
9699
}
97100

98101
Matcher messageMatcher = HTML_ERROR_REGEX.matcher(body);
99102
if (messageMatcher.find()) {
100-
errorBody.setMessage(messageMatcher.group(1).replaceAll("^[ .]+|[ .]+$", ""));
103+
errorBodyBuilder.setMessage(messageMatcher.group(1).replaceAll("^[ .]+|[ .]+$", ""));
101104
} else {
102-
errorBody.setMessage(
105+
errorBodyBuilder.setMessage(
103106
String.format(
104107
"Response from server (%s) %s: %s", response.getStatus(), body, err.getMessage()));
105108
}
106-
return errorBody;
109+
return errorBodyBuilder.build();
107110
}
108111
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ public boolean matches(ApiErrorBody body, Response resp) {
4747
return false;
4848
}
4949
if (this.errorCodeMatcher != null
50-
&& !this.errorCodeMatcher.matcher(body.getErrorCode()).matches()) {
50+
&& !this.errorCodeMatcher.matcher(body.errorCode()).matches()) {
5151
return false;
5252
}
5353
// Allow matching substring of the error message.
54-
if (this.messageMatcher != null && !this.messageMatcher.matcher(body.getMessage()).find()) {
54+
if (this.messageMatcher != null && !this.messageMatcher.matcher(body.message()).find()) {
5555
return false;
5656
}
5757
return true;
@@ -70,7 +70,7 @@ public T makeError(ApiErrorBody body) {
7070
&& parameterTypes[0].equals(String.class)
7171
&& parameterTypes[1].equals(List.class)) {
7272
try {
73-
return (T) constructor.newInstance(body.getMessage(), body.getErrorDetails());
73+
return (T) constructor.newInstance(body.message(), body.getErrorDetailsList());
7474
} catch (Exception e) {
7575
throw new DatabricksException(
7676
"Error creating custom error for error type " + this.customError.getName(), e);

0 commit comments

Comments
 (0)