All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.geotab.http.exception.ErrorHandler Maven / Gradle / Ivy
/*
*
* 2020 Copyright (C) Geotab Inc. All rights reserved.
*/
package com.geotab.http.exception;
import com.fasterxml.jackson.core.type.TypeReference;
import com.geotab.http.response.BaseResponse;
import com.geotab.model.enumeration.DbUnavailableState;
import com.geotab.model.error.Error;
import com.geotab.model.error.JsonRpcError;
import com.geotab.model.error.JsonRpcErrorCode;
import com.geotab.model.error.JsonRpcErrorData;
import com.geotab.model.serialization.ApiJsonSerializer;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.SerializationException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
/**
* Utility class which checks JSON response for error and transforms it to the corresponding
* exception.
*/
public final class ErrorHandler {
protected static final String EXCEPTION_MESSAGE_FORMAT =
"WebServerInvoker exception in a call to '{%s}': '{%s} {%s}'";
/**
* Checks if an error returned from MyGeotab.
*
* @param method The method in MyGeotab API.
* @param response The actual response from MyGeotab.
* @throws Exception Exception which can occur while executing the method.
*/
public static > void checkForError(String method,
R response) throws Exception {
JsonRpcError error = response != null ? response.getError() : null;
if (error == null) {
return;
}
Map innerErrors = null;
if (response.getError().getData() == null) {
// All MyGeotab servers honor our spec but GMS may not.
Pair> legacyError = convertLegacyError(response);
error = legacyError.getLeft();
innerErrors = legacyError.getRight();
}
String formattedMessage = String
.format(EXCEPTION_MESSAGE_FORMAT, method, error.getData().getType(), error.getMessage());
Exception exception = checkForError(formattedMessage,
new ServerInvokerJsonException(formattedMessage, null, innerErrors, error.getData()),
JsonRpcErrorCode.getByCode(error.getCode()), error.getData());
if (exception != null) {
if (exception instanceof JsonRpcErrorDataException) {
((JsonRpcErrorDataException) exception).setErrorData(error.getData());
}
throw exception;
}
}
private static Exception checkForError(String message, Exception innerException,
JsonRpcErrorCode errorCode, JsonRpcErrorData errorData) {
switch (errorCode) {
case INVALID_REQUEST:
return new InvalidRequestException(message, innerException);
case DB_UNAVAILABLE_GENERAL_ERROR:
case DB_UNAVAILABLE_CONNECTION_FAILURE:
case DB_UNAVAILABLE_INITIALIZING:
case DB_UNAVAILABLE_UNKNOWN_DATABASE:
case DB_UNAVAILABLE_OPERATION_ABORTED:
DbUnavailableState state = DbUnavailableState.NONE;
if (StringUtils.isNotEmpty(errorData.getInfo())) {
try {
Map errorDataInfo = ApiJsonSerializer.getInstance()
.getObjectMapper().readValue(
errorData.getInfo(), new TypeReference>() {
});
if (errorDataInfo.containsKey("state")) {
state = errorDataInfo.get("state");
}
} catch (IOException e) {
throw new IllegalStateException(
"Can not deserialize " + errorData.getInfo() + "to Map");
}
}
return new DbUnavailableException(message, innerException, state);
case METHOD_NOT_FOUND:
return new MissingMethodException(message, innerException);
case PARSE_ERROR:
return new SerializationException(message, innerException);
default:
return checkForErrorByErrorDataType(message, innerException, errorData);
}
}
private static Exception checkForErrorByErrorDataType(String message, Exception innerException,
JsonRpcErrorData errorData) {
if (StringUtils.isNotEmpty(errorData.getType())) {
switch (errorData.getType()) {
case "InvalidMyAdminUserException":
if (innerException instanceof ServerInvokerJsonException
&& ((ServerInvokerJsonException) innerException).getInnerError() != null) {
Map innerError = ((ServerInvokerJsonException) innerException)
.getInnerError();
if (innerError.containsKey("message")) {
String databaseName = innerError.get("message");
if (StringUtils.isNotEmpty(databaseName)) {
return new InvalidMyAdminUserException(databaseName);
}
}
}
return new InvalidMyAdminUserException();
case "InvalidUserException":
return new InvalidUserException();
case "InactiveUserException":
return new InactiveUserException();
case "DbUnavailableException":
return new DbUnavailableException(message, innerException);
case "RelationViolatedException":
return new RelationViolatedException(innerException);
case "GroupRelationViolatedException":
return new GroupRelationViolatedException(innerException);
case "DuplicateException":
return new DuplicateException(innerException);
case "PasswordPolicyViolationException":
return new PasswordPolicyViolationException(message);
case "RegistrationException":
return new RegistrationException(message);
case "OverLimitException":
return new OverLimitException(message);
case "InvalidRequestException":
return new IllegalStateException("Inconsistent JSON-RPC error code");
case "MethodNotFoundException":
case "MissingMethodException":
return new MissingMethodException(message, innerException);
case "MissingMemberException":
return new MissingMemberException(message, innerException);
case "NullReferenceException":
return new NullPointerException(message);
case "ArgumentException":
case "ArgumentOutOfRangeException":
return new IllegalArgumentException(message, innerException);
case "JsonSerializerException":
case "JSONSerializerException":
return new SerializationException(message, innerException);
case "InvalidCastException":
return new ClassCastException(message);
case "NotSupportedException":
return new NotImplementedException(message, innerException);
case "InvalidCertificateException":
return new CertificateException(message, innerException);
default:
return innerException;
}
}
return innerException;
}
@SuppressWarnings("Indentation")
protected static > Pair>
convertLegacyError(R response) {
Error[] errors = response.getError().getErrors();
String message = null;
String stack = null;
String name = null;
Map innerErrors = new HashMap<>(3);
for (Error item : errors) {
if (message == null && !(item.getMessage() == null)) {
message = item.getMessage();
innerErrors.put("message", message);
}
if (name == null && !(item.getName() == null)) {
name = item.getName();
innerErrors.put("name", name);
if (message == null) {
message = name;
}
}
if (stack == null && !(item.getStackTrace() == null)) {
stack = item.getStackTrace();
innerErrors.put("stackTrace", stack);
}
}
JsonRpcError error = response.getError();
if (name == null) {
name = error.getName();
if (message == null) {
// Reserve default error message in case the original exception provided no message.
message = name;
}
}
if (message == null) {
message = error.getMessage();
}
if (StringUtils.isNotEmpty(name) && !name.equals(message)) {
message = name + ": " + message;
}
JsonRpcError specError = JsonRpcError.builder()
.code(JsonRpcErrorCode.INTERNAL_ERROR.getCode())
.message(message)
.data(
JsonRpcErrorData.builder().type(name).requestIndex(response.getRequestIndex()).build())
.build();
return Pair.of(specError, innerErrors);
}
}