com.basho.riak.client.raw.JSONErrorParser Maven / Gradle / Ivy
/*
* This file is provided to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.basho.riak.client.raw;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.basho.riak.client.RiakException;
import com.basho.riak.client.raw.query.MapReduceTimeoutException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Exceptions come back from Riak as JSON, parses exceptions, and throws the
* most specific exception it can.
*
* @author russell
*
*/
public class JSONErrorParser {
private static final String PBSOCKET_PRE_1_1_TIMEOUT_TUPLE = "{error,timeout}";
private static final String PARSE_ERROR = ". Additionally, an error was thrown parsing the error response.";
private static final String ERROR_KEY = "error";
private static final String TIMEOUT_VALUE = "timeout";
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* Parses some Riak error json
into a checked exception of the
* most specific type it can manage.
*
* @param json
* The error from Riak
* @return a {@link RiakException} as specific as possible
* @throws IOException
*/
public static RiakException parseException(final String json) {
RiakException ex = null;
try {
Map exceptionData = parseError(json);
if (isTimeoutError(exceptionData)) {
ex = new MapReduceTimeoutException();
} else {
ex = new RiakException(json);
}
} catch (IOException e) {
ex = new RiakException(new StringBuilder().append(json).append(PARSE_ERROR).toString(), e);
}
return ex;
}
/**
* Does the json
represent a riak map/reduce timeout exception?
*
* @param json
* an error String from Riak
* @return true if json
represents an m/r timeout, false
* otherwse
* @throws IOException
*/
public static boolean isTimeoutException(final String json) {
try {
Map exceptionData = parseError(json);
return isTimeoutError(exceptionData);
} catch (IOException e) {
// what about an old skool Erlang term exception from the PB Socket?
// fall back to the string match on 'timeout'
// TODO: @remove:1.2
if (PBSOCKET_PRE_1_1_TIMEOUT_TUPLE.equals(json)) {
return true;
}
// can't be a timeout if we can't parse it
return false;
}
}
/**
* Internal parse method, just calls ObjectMapper to get a map from the
* string
*
* @param json
* a JSON String
* @return the Map representation of the JSON
* @throws IOException
*/
private static final Map parseError(final String json) throws IOException {
return objectMapper.readValue(json, objectMapper.getTypeFactory().constructMapType(HashMap.class, String.class, String.class));
}
/**
* Does the map of exception data represent an m/r timeout exception?
*
* @param exceptionData
* @return true if exceptionData
contains key "error" with
* value "timeout". False otherwise.
*/
private static boolean isTimeoutError(final Map exceptionData) {
return (exceptionData.containsKey(ERROR_KEY) && TIMEOUT_VALUE.equals(exceptionData.get(ERROR_KEY)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy