From 694e7732616c5bbdb208b4a8b0f0558c75654b06 Mon Sep 17 00:00:00 2001 From: skyflow-vivek Date: Wed, 26 Mar 2025 14:09:01 +0530 Subject: [PATCH 1/2] SK-1969 Fix error handling for certain scenarios --- .../java/com/skyflow/errors/ErrorMessage.java | 26 ++++---- .../com/skyflow/errors/SkyflowException.java | 61 ++++++++++--------- .../java/com/skyflow/utils/Constants.java | 1 + 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/skyflow/errors/ErrorMessage.java b/src/main/java/com/skyflow/errors/ErrorMessage.java index da992da2..33833443 100644 --- a/src/main/java/com/skyflow/errors/ErrorMessage.java +++ b/src/main/java/com/skyflow/errors/ErrorMessage.java @@ -3,27 +3,27 @@ import com.skyflow.utils.Constants; public enum ErrorMessage { - // client initialization + // Client initialization VaultIdAlreadyInConfigList("%s0 Validation error. VaultId is present in an existing config. Specify a new vaultId in config."), VaultIdNotInConfigList("%s0 Validation error. VaultId is missing from the config. Specify the vaultIds from configs."), ConnectionIdAlreadyInConfigList("%s0 Validation error. ConnectionId is present in an existing config. Specify a connectionId in config."), ConnectionIdNotInConfigList("%s0 Validation error. ConnectionId is missing from the config. Specify the connectionIds from configs."), EmptyCredentials("%s0 Validation error. Invalid credentials. Credentials must not be empty."), - // vault config + // Vault config InvalidVaultId("%s0 Initialization failed. Invalid vault ID. Specify a valid vault ID."), EmptyVaultId("%s0 Initialization failed. Invalid vault ID. Vault ID must not be empty."), InvalidClusterId("%s0 Initialization failed. Invalid cluster ID. Specify cluster ID."), EmptyClusterId("%s0 Initialization failed. Invalid cluster ID. Specify a valid cluster ID."), - // connection config + // Connection config InvalidConnectionId("%s0 Initialization failed. Invalid connection ID. Specify a valid connection ID."), EmptyConnectionId("%s0 Initialization failed. Invalid connection ID. Connection ID must not be empty."), InvalidConnectionUrl("%s0 Initialization failed. Invalid connection URL. Specify a valid connection URL."), EmptyConnectionUrl("%s0 Initialization failed. Invalid connection URL. Connection URL must not be empty."), InvalidConnectionUrlFormat("%s0 Initialization failed. Connection URL is not a valid URL. Specify a valid connection URL."), - // credentials + // Credentials MultipleTokenGenerationMeansPassed("%s0 Initialization failed. Invalid credentials. Specify only one from 'path', 'credentialsString', 'token' or 'apiKey'."), NoTokenGenerationMeansPassed("%s0 Initialization failed. Invalid credentials. Specify any one from 'path', 'credentialsString', 'token' or 'apiKey'."), EmptyCredentialFilePath("%s0 Initialization failed. Invalid credentials. Credentials file path must not be empty."), @@ -35,7 +35,7 @@ public enum ErrorMessage { EmptyRoleInRoles("%s0 Initialization failed. Invalid role. Specify a valid role."), EmptyContext("%s0 Initialization failed. Invalid context. Specify a valid context."), - // bearer token generation + // Bearer token generation FileNotFound("%s0 Initialization failed. Credential file not found at %s1. Verify the file path."), FileInvalidJson("%s0 Initialization failed. File at %s1 is not in valid JSON format. Verify the file contents."), CredentialsStringInvalidJson("%s0 Initialization failed. Credentials string is not in valid JSON format. Verify the credentials string contents."), @@ -52,7 +52,7 @@ public enum ErrorMessage { MissingAccessToken("%s0 Validation error. Access token not present in the response from bearer token generation. Verify your credentials."), MissingTokenType("%s0 Validation error. Token type not present in the response from bearer token generation. Verify your credentials."), - // insert + // Insert TableKeyError("%s0 Validation error. 'table' key is missing from the payload. Specify a 'table' key."), EmptyTable("%s0 Validation error. 'table' can't be empty. Specify a table."), ValuesKeyError("%s0 Validation error. 'values' key is missing from the payload. Specify a 'values' key."), @@ -72,12 +72,12 @@ public enum ErrorMessage { BatchInsertPartialSuccess("%s0 Insert operation completed with partial success."), BatchInsertFailure("%s0 Insert operation failed."), - // detokenize + // Detokenize InvalidDetokenizeData("%s0 Validation error. Invalid detokenize data. Specify valid detokenize data."), EmptyDetokenizeData("%s0 Validation error. Invalid data tokens. Specify at least one data token."), EmptyTokenInDetokenizeData("%s0 Validation error. Invalid data tokens. Specify a valid data token."), - // get interface + // Get IdsKeyError("%s0 Validation error. 'ids' key is missing from the payload. Specify an 'ids' key."), EmptyIds("%s0 Validation error. 'ids' can't be empty. Specify at least one id."), EmptyIdInIds("%s0 Validation error. Invalid id in 'ids'. Specify a valid id."), @@ -99,22 +99,22 @@ public enum ErrorMessage { TokenKeyError("%s0 Validation error. 'token' key is missing from the payload. Specify a 'token' key."), PartialSuccess("%s0 Validation error. Check 'SkyflowError.data' for details."), - // update + // Update DataKeyError("%s0 Validation error. 'data' key is missing from the payload. Specify a 'data' key."), EmptyData("%s0 Validation error. 'data' can't be empty. Specify data."), SkyflowIdKeyError("%s0 Validation error. 'skyflow_id' is missing from the data payload. Specify a 'skyflow_id'."), InvalidSkyflowIdType("%s0 Validation error. Invalid type for 'skyflow_id' in data payload. Specify 'skyflow_id' as a string."), EmptySkyflowId("%s0 Validation error. 'skyflow_id' can't be empty. Specify a skyflow id."), - // query + // Query QueryKeyError("%s0 Validation error. 'query' key is missing from the payload. Specify a 'query' key."), EmptyQuery("%s0 Validation error. 'query' can't be empty. Specify a query"), - // tokenize + // Tokenize ColumnValuesKeyErrorTokenize("%s0 Validation error. 'columnValues' key is missing from the payload. Specify a 'columnValues' key."), EmptyColumnGroupInColumnValue("%s0 Validation error. Invalid column group in column value. Specify a valid column group."), - // connection + // Connection InvalidRequestHeaders("%s0 Validation error. Request headers aren't valid. Specify valid request headers."), EmptyRequestHeaders("%s0 Validation error. Request headers are empty. Specify valid request headers."), InvalidPathParams("%s0 Validation error. Path parameters aren't valid. Specify valid path parameters."), @@ -124,6 +124,8 @@ public enum ErrorMessage { InvalidRequestBody("%s0 Validation error. Invalid request body. Specify the request body as an object."), EmptyRequestBody("%s0 Validation error. Request body can't be empty. Specify a valid request body."), + // Generic + ErrorOccurred("%s0 API error. Error occurred.") ; private final String message; diff --git a/src/main/java/com/skyflow/errors/SkyflowException.java b/src/main/java/com/skyflow/errors/SkyflowException.java index a455521d..32c71f39 100644 --- a/src/main/java/com/skyflow/errors/SkyflowException.java +++ b/src/main/java/com/skyflow/errors/SkyflowException.java @@ -1,6 +1,10 @@ package com.skyflow.errors; -import com.google.gson.*; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.skyflow.utils.Constants; import java.util.List; import java.util.Map; @@ -39,24 +43,25 @@ public SkyflowException(int code, String message) { public SkyflowException(int httpCode, Throwable cause, Map> responseHeaders, String responseBody) { super(cause); - this.httpCode = httpCode; - setRequestId(responseHeaders); - setResponseBody(responseBody, responseHeaders); + this.httpCode = httpCode > 0 ? httpCode : 400; + try { + setRequestId(responseHeaders); + setResponseBody(responseBody, responseHeaders); + } catch (Exception e) { + this.httpStatus = HttpStatus.BAD_REQUEST.getHttpStatus(); + String fullMessage = responseBody != null ? responseBody : + (cause.getLocalizedMessage() != null ? cause.getMessage() : ErrorMessage.ErrorOccurred.getMessage()); + this.message = fullMessage.split("HTTP response code:")[0].trim(); + } } private void setResponseBody(String responseBody, Map> responseHeaders) { - try { - if (responseBody != null) { - this.responseBody = JsonParser.parseString(responseBody).getAsJsonObject(); - if (this.responseBody.get("error") != null) { - setGrpcCode(); - setHttpStatus(); - setMessage(); - setDetails(responseHeaders); - } - } - } catch (JsonSyntaxException e) { - throw new RuntimeException(e); + this.responseBody = JsonParser.parseString(responseBody).getAsJsonObject(); + if (this.responseBody.get("error") != null) { + setGrpcCode(); + setHttpStatus(); + setMessage(); + setDetails(responseHeaders); } } @@ -65,10 +70,8 @@ public String getRequestId() { } private void setRequestId(Map> responseHeaders) { - if (responseHeaders != null) { - List ids = responseHeaders.get("x-request-id"); - this.requestId = ids == null ? null : ids.get(0); - } + List ids = responseHeaders.get(Constants.REQUEST_ID_HEADER_KEY); + this.requestId = ids == null ? null : ids.get(0); } private void setMessage() { @@ -86,9 +89,17 @@ private void setHttpStatus() { this.httpStatus = statusElement == null ? null : statusElement.getAsString(); } + public int getHttpCode() { + return httpCode; + } + + public JsonArray getDetails() { + return details; + } + private void setDetails(Map> responseHeaders) { JsonElement detailsElement = ((JsonObject) responseBody.get("error")).get("details"); - List errorFromClientHeader = responseHeaders.get("error-from-client"); + List errorFromClientHeader = responseHeaders.get(Constants.ERROR_FROM_CLIENT_HEADER_KEY); if (detailsElement != null) { this.details = detailsElement.getAsJsonArray(); } @@ -101,14 +112,6 @@ private void setDetails(Map> responseHeaders) { } } - public int getHttpCode() { - return httpCode; - } - - public JsonArray getDetails() { - return details; - } - public Integer getGrpcCode() { return grpcCode; } diff --git a/src/main/java/com/skyflow/utils/Constants.java b/src/main/java/com/skyflow/utils/Constants.java index b0620609..500d8c94 100644 --- a/src/main/java/com/skyflow/utils/Constants.java +++ b/src/main/java/com/skyflow/utils/Constants.java @@ -25,4 +25,5 @@ public final class Constants { public static final String SDK_AUTH_HEADER_KEY = "x-skyflow-authorization"; public static final String SDK_METRICS_HEADER_KEY = "sky-metadata"; public static final String REQUEST_ID_HEADER_KEY = "x-request-id"; + public static final String ERROR_FROM_CLIENT_HEADER_KEY = "error-from-client"; } From cf242b107627d117b5276d71e44283949f5236ab Mon Sep 17 00:00:00 2001 From: skyflow-vivek Date: Mon, 7 Apr 2025 06:33:28 +0000 Subject: [PATCH 2/2] [AUTOMATED] Private Release 2.0.0-beta.1-dev-ec349a9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f61f9c3..84dfe438 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.skyflow skyflow-java - 2.0.0-beta.1-dev.9f386ac + 2.0.0-beta.1-dev.ec349a9 jar ${project.groupId}:${project.artifactId}