Skip to content

Commit

Permalink
Improve error response to the client. Added errorType so that client …
Browse files Browse the repository at this point in the history
…can handle better than depending on the http status codes (open-metadata#14784)
  • Loading branch information
harshach authored Jan 21, 2024
1 parent 62d1ef7 commit 15eb094
Show file tree
Hide file tree
Showing 28 changed files with 297 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ public PipelineServiceClientResponse deployPipeline(
}
} catch (IOException | URISyntaxException e) {
throw IngestionPipelineDeploymentException.byMessage(
ingestionPipeline.getName(), e.getMessage());
ingestionPipeline.getName(), DEPLOYEMENT_ERROR, e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw IngestionPipelineDeploymentException.byMessage(
ingestionPipeline.getName(), e.getMessage());
ingestionPipeline.getName(), DEPLOYEMENT_ERROR, e.getMessage());
}
throw new PipelineServiceClientException(
String.format(
Expand Down Expand Up @@ -181,14 +181,17 @@ public PipelineServiceClientResponse runPipeline(
return getResponse(200, response.body());
}
} catch (IOException | URISyntaxException e) {
throw IngestionPipelineDeploymentException.byMessage(pipelineName, e.getMessage());
throw IngestionPipelineDeploymentException.byMessage(
pipelineName, TRIGGER_ERROR, e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw IngestionPipelineDeploymentException.byMessage(pipelineName, e.getMessage());
throw IngestionPipelineDeploymentException.byMessage(
pipelineName, TRIGGER_ERROR, e.getMessage());
}

throw IngestionPipelineDeploymentException.byMessage(
pipelineName,
TRIGGER_ERROR,
"Failed to trigger IngestionPipeline",
Response.Status.fromStatusCode(response.statusCode()));
}
Expand Down Expand Up @@ -318,10 +321,12 @@ public PipelineServiceClientResponse runAutomationsWorkflow(Workflow workflow) {
return getResponse(200, response.body());
}
} catch (IOException | URISyntaxException e) {
throw IngestionPipelineDeploymentException.byMessage(workflow.getName(), e.getMessage());
throw IngestionPipelineDeploymentException.byMessage(
workflow.getName(), TRIGGER_ERROR, e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw IngestionPipelineDeploymentException.byMessage(workflow.getName(), e.getMessage());
throw IngestionPipelineDeploymentException.byMessage(
workflow.getName(), TRIGGER_ERROR, e.getMessage());
}
throw new PipelineServiceClientException(
String.format(
Expand Down Expand Up @@ -354,10 +359,12 @@ private PipelineServiceClientResponse sendPost(String endpoint, Object request)
return getResponse(200, response.body());
}
} catch (IOException | URISyntaxException e) {
throw IngestionPipelineDeploymentException.byMessage(workflowPayload, e.getMessage());
throw IngestionPipelineDeploymentException.byMessage(
workflowPayload, DEPLOYEMENT_ERROR, e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw IngestionPipelineDeploymentException.byMessage(workflowPayload, e.getMessage());
throw IngestionPipelineDeploymentException.byMessage(
workflowPayload, DEPLOYEMENT_ERROR, e.getMessage());
}
throw new PipelineServiceClientException(
String.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@

public final class BadRequestException extends WebServiceException {
private static final String DEFAULT_MESSAGE = "Bad request.";
private static final String ERROR_TYPE = "BAD_REQUEST";

private BadRequestException() {
super(Response.Status.BAD_REQUEST, DEFAULT_MESSAGE);
super(Response.Status.BAD_REQUEST, ERROR_TYPE, DEFAULT_MESSAGE);
}

public static BadRequestException of() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,22 @@
import org.openmetadata.service.util.JsonUtils;

public final class CatalogExceptionMessage {

public static final String FAILED_SEND_EMAIL = "FAILED_SEND_EMAIL";
public static final String EMAIL_SENDING_ISSUE =
"There is some issue in sending the Mail. Please contact your administrator.";
public static final String PASSWORD_INVALID_FORMAT =
"Password must be of minimum 8 characters, with one special, one Upper, one lower case character, and one Digit.";
public static final String MAX_FAILED_LOGIN_ATTEMPT =
"Failed Login Attempts Exceeded. Please try after some time.";

public static final String INCORRECT_OLD_PASSWORD = "INCORRECT_OLD_PASSWORD";

public static final String INVALID_USER_OR_PASSWORD = "INVALID_USER_OR_PASSWORD";
public static final String INVALID_USERNAME_PASSWORD =
"You have entered an invalid username or password.";

public static final String PASSWORD_RESET_TOKEN_EXPIRED = "PASSWORD_RESET_TOKEN_EXPIRED";
public static final String ENTITY_ALREADY_EXISTS = "Entity already exists";
public static final String FERNET_KEY_NULL = "Fernet key is null";
public static final String FIELD_NOT_TOKENIZED = "Field is not tokenized";
Expand All @@ -62,17 +70,26 @@ public final class CatalogExceptionMessage {
"Unexpected error occurred while building the teams hierarchy";
public static final String LDAP_MISSING_ATTR =
"Username or Email Attribute is incorrect. Please check Openmetadata Configuration.";
public static final String MULTIPLE_EMAIL_ENTRIES_ERROR = "MULTIPLE_EMAIL_ENTRIES_ERROR";
public static final String MULTIPLE_EMAIL_ENTRIES =
"Email corresponds to multiple entries in Directory.";

public static final String INVALID_EMAIL_PASSWORD =
"You have entered an invalid email or password.";

public static final String EMAIL_EXISTS = "EMAIL_EXISTS";

public static final String SELF_SIGNUP_NOT_ENABLED = "SELF_SIGNUP_NOT_ENABLED";
public static final String SELF_SIGNUP_ERROR = "Signup is not supported.";
public static final String NOT_IMPLEMENTED_METHOD = "Method not implemented.";

public static final String AUTHENTICATOR_OPERATION_NOT_SUPPORTED =
"AUTHENTICATOR_OPERATION_NOT_SUPPORTED";
public static final String FORBIDDEN_AUTHENTICATOR_OP =
"Operation is not permitted with the Selected Authenticator.";

public static final String INVALID_TOKEN = "INVALID_TOKEN";
public static final String TOKEN_EXPIRED = "TOKEN_EXPIRED";
public static final String TOKEN_EXPIRY_ERROR =
"Email Verification Token %s is expired. Please issue a new request for email verification.";
public static final String INVALID_BOT_USER = "Revoke Token can only be applied to Bot Users.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import org.openmetadata.sdk.exception.WebServiceException;

public class CustomExceptionMessage extends WebServiceException {
public CustomExceptionMessage(Response.Status status, String message) {
super(status.getStatusCode(), message);
public CustomExceptionMessage(Response.Status status, String errorType, String message) {
super(status.getStatusCode(), errorType, message);
}

public CustomExceptionMessage(int status, String message) {
super(status, message);
public CustomExceptionMessage(int status, String errorType, String message) {
super(status, errorType, message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
import org.openmetadata.sdk.exception.WebServiceException;

public class EntityMaskException extends WebServiceException {
private static final String ERROR_TYPE = "ENTITY_MASK_ERROR";

public EntityMaskException(String message) {
super(Response.Status.INTERNAL_SERVER_ERROR, message);
super(Response.Status.INTERNAL_SERVER_ERROR, ERROR_TYPE, message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ public class EntityNotFoundException extends WebServiceException {
private static final String BY_PARSER_SCHEMA_MESSAGE =
"Parser schema not found for entity with id [%s].";

private static final String ERROR_TYPE = "ENTITY_NOT_FOUND";

public EntityNotFoundException(String message) {
super(Response.Status.NOT_FOUND, message);
super(Response.Status.NOT_FOUND, ERROR_TYPE, message);
}

private EntityNotFoundException(String message, Throwable cause) {
super(Response.Status.NOT_FOUND, message, cause);
super(Response.Status.NOT_FOUND, ERROR_TYPE, message, cause);
}

public static EntityNotFoundException byId(String id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import org.openmetadata.sdk.exception.WebServiceException;

public class IncidentManagerException extends WebServiceException {
private static final String ERROR_TYPE = "INCIDENT_INVALID_STATUS";

protected IncidentManagerException(Response.Status status, String message) {
super(status.getStatusCode(), message);
super(status.getStatusCode(), ERROR_TYPE, message);
}

public IncidentManagerException(String message) {
super(Response.Status.INTERNAL_SERVER_ERROR, message);
super(Response.Status.INTERNAL_SERVER_ERROR, ERROR_TYPE, message);
}

public static IncidentManagerException invalidStatus(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,27 @@
public class IngestionPipelineDeploymentException extends WebServiceException {

private static final String BY_NAME_MESSAGE = "Failed to deploy pipeline [%s] due to [%s].";
private static final String ERROR_TYPE = "DEPLOYMENT_ERROR";

public IngestionPipelineDeploymentException(String message) {
super(Response.Status.BAD_REQUEST, message);
super(Response.Status.BAD_REQUEST, ERROR_TYPE, message);
}

private IngestionPipelineDeploymentException(Response.Status status, String message) {
super(status, message);
private IngestionPipelineDeploymentException(
Response.Status status, String errorType, String message) {
super(status, errorType, message);
}

public static IngestionPipelineDeploymentException byMessage(
String name, String errorMessage, Response.Status status) {
return new IngestionPipelineDeploymentException(status, buildMessageByName(name, errorMessage));
String name, String errorType, String errorMessage, Response.Status status) {
return new IngestionPipelineDeploymentException(
status, errorType, buildMessageByName(name, errorMessage));
}

public static IngestionPipelineDeploymentException byMessage(String name, String errorMessage) {
public static IngestionPipelineDeploymentException byMessage(
String name, String errorType, String errorMessage) {
return new IngestionPipelineDeploymentException(
Response.Status.BAD_REQUEST, buildMessageByName(name, errorMessage));
Response.Status.BAD_REQUEST, errorType, buildMessageByName(name, errorMessage));
}

public static String buildMessageByName(String name, String errorMessage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
public class InvalidServiceConnectionException extends WebServiceException {
private static final String BY_NAME_MESSAGE =
"InvalidServiceConnectionException for service [%s] due to [%s].";
private static final String ERROR_TYPE = "INVALID_SERVICE_EXCEPTION";

public InvalidServiceConnectionException(String message) {
super(Response.Status.BAD_REQUEST, message);
super(Response.Status.BAD_REQUEST, ERROR_TYPE, message);
}

private InvalidServiceConnectionException(Response.Status status, String message) {
super(status, message);
super(status, ERROR_TYPE, message);
}

public static InvalidServiceConnectionException byMessage(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

public class ReflectionException extends WebServiceException {

public static final String REFLECTION_ERROR = "REFLECTION_ERROR";

public ReflectionException(String message) {
super(Response.Status.INTERNAL_SERVER_ERROR, message);
super(Response.Status.INTERNAL_SERVER_ERROR, REFLECTION_ERROR, message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ public class SecretsManagerException extends WebServiceException {
private static final String BY_NAME_MESSAGE =
"SecretsManagerException for secret manager [%s] when using the secret name [%s] due to [%s].";

public static final String SECRETS_MANAGER_ERROR = "SECRETS_MANAGER_ERROR";

public SecretsManagerException(String message) {
super(Response.Status.INTERNAL_SERVER_ERROR, message);
super(Response.Status.INTERNAL_SERVER_ERROR, SECRETS_MANAGER_ERROR, message);
}

public SecretsManagerException(Response.Status status, String message) {
super(status.getStatusCode(), message);
super(status.getStatusCode(), SECRETS_MANAGER_ERROR, message);
}

public static SecretsManagerException byMessage(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@ public class UnhandledServerException extends WebServiceException {
private static final String MESSAGE =
"An exception with message [%s] was thrown while processing request.";

public static final String UNHANDLED_ERROR = "REFLECTION_ERROR";

public UnhandledServerException(String exceptionMessage) {
super(Response.Status.INTERNAL_SERVER_ERROR, String.format(MESSAGE, exceptionMessage));
super(
Response.Status.INTERNAL_SERVER_ERROR,
UNHANDLED_ERROR,
String.format(MESSAGE, exceptionMessage));
}

public UnhandledServerException(String exceptionMessage, Throwable cause) {
super(Response.Status.INTERNAL_SERVER_ERROR, String.format(MESSAGE, exceptionMessage), cause);
super(
Response.Status.INTERNAL_SERVER_ERROR,
UNHANDLED_ERROR,
String.format(MESSAGE, exceptionMessage),
cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ public void updateSetting(Settings setting) {
SettingsCache.invalidateSettings(setting.getConfigType().value());
} catch (Exception ex) {
LOG.error("Failing in Updating Setting.", ex);
throw new CustomExceptionMessage(Response.Status.INTERNAL_SERVER_ERROR, ex.getMessage());
throw new CustomExceptionMessage(
Response.Status.INTERNAL_SERVER_ERROR,
"FAILED_TO_UPDATE_SLACK_OR_EMAIL",
ex.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,8 @@ public Response createAccessToken(
UserTokenCache.invalidateToken(user.getName());
return Response.status(Response.Status.OK).entity(personalAccessToken).build();
}
throw new CustomExceptionMessage(BAD_REQUEST, "Bots cannot have a Personal Access Token.");
throw new CustomExceptionMessage(
BAD_REQUEST, "NO_PERSONAL_TOKEN_FOR_BOTS", "Bots cannot have a Personal Access Token.");
}

@GET
Expand Down Expand Up @@ -1371,7 +1372,8 @@ public static User getUser(String updatedBy, CreateUser create) {

public void validateEmailAlreadyExists(String email) {
if (repository.checkEmailAlreadyExists(email)) {
throw new CustomExceptionMessage(BAD_REQUEST, "User with Email Already Exists");
throw new CustomExceptionMessage(
BAD_REQUEST, "EMAIL_EXISTS", "User with Email Already Exists");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public interface SearchClient {
String REMOVE_TEST_SUITE_CHILDREN_SCRIPT =
"for (int i = 0; i < ctx._source.testSuites.length; i++) { if (ctx._source.testSuites[i].id == '%s') { ctx._source.testSuites.remove(i) }}";

String NOT_IMPLEMENTED_ERROR_TYPE = "NOT_IMPLEMENTED";

boolean isClientAvailable();

ElasticSearchConfiguration.SearchType getSearchType();
Expand Down Expand Up @@ -128,22 +130,26 @@ Response listDataInsightChartResult(
throws IOException, ParseException;

default BulkResponse bulk(BulkRequest data, RequestOptions options) throws IOException {
throw new CustomExceptionMessage(Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_METHOD);
throw new CustomExceptionMessage(
Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_ERROR_TYPE, NOT_IMPLEMENTED_METHOD);
}

default es.org.elasticsearch.action.bulk.BulkResponse bulk(
es.org.elasticsearch.action.bulk.BulkRequest data,
es.org.elasticsearch.client.RequestOptions options)
throws IOException {
throw new CustomExceptionMessage(Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_METHOD);
throw new CustomExceptionMessage(
Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_ERROR_TYPE, NOT_IMPLEMENTED_METHOD);
}

default int getSuccessFromBulkResponse(BulkResponse response) {
throw new CustomExceptionMessage(Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_METHOD);
throw new CustomExceptionMessage(
Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_ERROR_TYPE, NOT_IMPLEMENTED_METHOD);
}

default int getSuccessFromBulkResponse(es.org.elasticsearch.action.bulk.BulkResponse response) {
throw new CustomExceptionMessage(Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_METHOD);
throw new CustomExceptionMessage(
Response.Status.NOT_IMPLEMENTED, NOT_IMPLEMENTED_ERROR_TYPE, NOT_IMPLEMENTED_METHOD);
}

void close();
Expand Down
Loading

0 comments on commit 15eb094

Please sign in to comment.