blob: 213e2f5779f6654cdf86c35999574b41001f887e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file 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.
*/
#include <map>
#include <string>
#include <geode/ExceptionTypes.hpp>
#include "ErrType.hpp"
#include "util/Log.hpp"
namespace {
using apache::geode::client::AllConnectionsInUseException;
using apache::geode::client::AuthenticationFailedException;
using apache::geode::client::AuthenticationRequiredException;
using apache::geode::client::BufferSizeExceededException;
using apache::geode::client::CacheClosedException;
using apache::geode::client::CacheListenerException;
using apache::geode::client::CacheLoaderException;
using apache::geode::client::CacheProxyException;
using apache::geode::client::CacheServerException;
using apache::geode::client::CacheWriterException;
using apache::geode::client::CommitConflictException;
using apache::geode::client::ConcurrentModificationException;
using apache::geode::client::DiskFailureException;
using apache::geode::client::DuplicateDurableClientException;
using apache::geode::client::EntryDestroyedException;
using apache::geode::client::EntryExistsException;
using apache::geode::client::EntryNotFoundException;
using apache::geode::client::FunctionExecutionException;
using apache::geode::client::GeodeIOException;
using apache::geode::client::IllegalArgumentException;
using apache::geode::client::IllegalStateException;
using apache::geode::client::LeaseExpiredException;
using apache::geode::client::LowMemoryException;
using apache::geode::client::MessageException;
using apache::geode::client::NoAvailableLocatorsException;
using apache::geode::client::NoSystemException;
using apache::geode::client::NotAuthorizedException;
using apache::geode::client::NotConnectedException;
using apache::geode::client::NotOwnerException;
using apache::geode::client::OutOfMemoryException;
using apache::geode::client::PutAllPartialResultException;
using apache::geode::client::QueryException;
using apache::geode::client::QueryExecutionLowMemoryException;
using apache::geode::client::RegionDestroyedException;
using apache::geode::client::RegionExistsException;
using apache::geode::client::RollbackException;
using apache::geode::client::StatisticsDisabledException;
using apache::geode::client::TimeoutException;
using apache::geode::client::TransactionDataNodeHasDepartedException;
using apache::geode::client::TransactionDataRebalancedException;
using apache::geode::client::UnknownException;
[[noreturn]] void notConnectedException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": not connected to Geode");
throw NotConnectedException{message};
}
[[noreturn]] void messageException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg
: ": message from server could not be handled");
throw MessageException{message};
}
[[noreturn]] void cacheServerException(std::string message, std::string& exMsg,
GfErrType err, std::string) {
if (err == GF_CACHESERVER_EXCEPTION) {
message.append(!exMsg.empty() ? exMsg
: ": exception happened at cache server");
}
if (err == GF_CACHE_REGION_NOT_FOUND) {
message.append(!exMsg.empty() ? exMsg : ": region not found on server");
}
throw CacheServerException{message};
}
[[noreturn]] void notOwnerException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": not own the lock");
throw NotOwnerException{message};
}
[[noreturn]] void illegalStateException(std::string message, std::string& exMsg,
GfErrType err, std::string) {
if (err == GF_CACHE_REGION_NOT_GLOBAL) {
message.append(!exMsg.empty() ? exMsg : ": region not global");
}
if (err == GF_CACHE_ILLEGAL_STATE_EXCEPTION) {
message.append(!exMsg.empty() ? exMsg : ": illegal State");
}
throw IllegalStateException{message};
}
[[noreturn]] void illegalArgumentException(std::string message,
std::string& exMsg,
GfErrType err, std::string) {
if (err == GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION) {
message.append(!exMsg.empty() ? exMsg : ": illegal argument");
}
if (err == GF_CACHE_REGION_KEYS_NOT_STRINGS) {
message.append(!exMsg.empty() ? exMsg
: ": region entries do not support C access");
}
if (err == GF_CACHE_REGION_ENTRY_NOT_BYTES) {
message.append(!exMsg.empty()
? exMsg
: ": existing non-null values was not a byte array");
}
throw IllegalArgumentException{message};
}
[[noreturn]] void cacheWriterException(std::string message, std::string& exMsg,
GfErrType err, std::string) {
if (err == GF_CACHE_WRITER_EXCEPTION) {
message.append(!exMsg.empty() ? exMsg
: ": exception on server during write");
}
if (err == GF_CACHEWRITER_ERROR) {
message.append(!exMsg.empty() ? exMsg : ": exception in CacheWriter");
}
throw CacheWriterException{message};
}
[[noreturn]] void cacheLoaderException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": exception in CacheLoader");
throw CacheLoaderException{message};
}
[[noreturn]] void cacheListenerException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": exception in CacheListener");
throw CacheListenerException{message};
}
[[noreturn]] void regionDestroyedException(std::string message,
std::string& exMsg,
GfErrType err, std::string) {
if (err == GF_CACHE_REGION_INVALID) {
message.append(!exMsg.empty() ? exMsg : ": region not valid");
}
if (err == GF_CACHE_REGION_DESTROYED_EXCEPTION) {
message.append(!exMsg.empty() ? exMsg : ": Named Region Destroyed");
}
throw RegionDestroyedException{message};
}
[[noreturn]] void cacheProxyException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": error in Cache proxy");
throw CacheProxyException{message};
}
[[noreturn]] void geodeIOException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Input/Output error in operation");
throw GeodeIOException{message};
}
[[noreturn]] void noSystemException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": entity does not exist");
throw NoSystemException{message};
}
[[noreturn]] void timeoutException(std::string message, std::string& exMsg,
GfErrType err, std::string) {
if (err == GF_CLIENT_WAIT_TIMEOUT) {
message.append(!exMsg.empty()
? exMsg
: ": timed out, possibly bucket is not available.");
} else {
message.append(!exMsg.empty() ? exMsg : ": timed out");
}
throw TimeoutException{message};
}
[[noreturn]] void outOfMemoryException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Out of memory");
throw OutOfMemoryException{message};
}
[[noreturn]] void bufferSizeExceededException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Buffer Size Exceeded");
throw BufferSizeExceededException{message};
}
[[noreturn]] void leaseExpiredException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": lock Lease Expired On you");
throw LeaseExpiredException{message};
}
[[noreturn]] void regionExistsException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Named Region Exists");
throw RegionExistsException{message};
}
[[noreturn]] void entryNotFoundException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Entry not found");
throw EntryNotFoundException{message};
}
[[noreturn]] void entryExistsException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg
: ": Entry already exists in the region");
throw EntryExistsException{message};
}
[[noreturn]] void entryDestroyedException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Entry has been destroyed");
throw EntryDestroyedException{message};
}
[[noreturn]] void cacheClosedException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Cache has been closed");
throw CacheClosedException{message};
}
[[noreturn]] void statisticsDisabledException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty()
? exMsg
: ": Statistics have been disabled for the region");
throw StatisticsDisabledException{message};
}
[[noreturn]] void concurrentModificationException(std::string message,
std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg
: ": Concurrent modification in the cache");
throw ConcurrentModificationException{message};
}
[[noreturn]] void notAuthorizedException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": unauthorized operation");
throw NotAuthorizedException{message};
}
[[noreturn]] void authenticationFailedException(std::string message,
std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": authentication failed");
throw AuthenticationFailedException{message};
}
[[noreturn]] void authenticationRequiredException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": no authentication provided");
throw AuthenticationRequiredException{message};
}
[[noreturn]] void duplicateDurableClientException(std::string message,
std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Duplicate Durable Client Id");
throw DuplicateDurableClientException{message};
}
[[noreturn]] void queryException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Query failed");
throw QueryException{message};
}
[[noreturn]] void noAvailableLocatorsException(std::string,
std::string& exMsg,
GfErrType,
std::string func) {
try {
throw NoAvailableLocatorsException{
func + (!exMsg.empty() ? exMsg : ": No locators available")};
} catch (...) {
std::throw_with_nested(NotConnectedException{
func + (!exMsg.empty() ? exMsg : ": No locators available")});
}
}
[[noreturn]] void allConnectionsInUseException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": All connections are in use");
throw AllConnectionsInUseException{message};
}
[[noreturn]] void functionExecutionException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Function execution failed");
throw FunctionExecutionException{message};
}
[[noreturn]] void diskFailureException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Disk full");
throw DiskFailureException{message};
}
[[noreturn]] void rollbackException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Transaction rolled back");
throw RollbackException{message};
}
[[noreturn]] void commitConflictException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg : ": Commit conflict exception");
throw CommitConflictException{message};
}
[[noreturn]] void transactionDataRebalancedException(std::string message,
std::string& exMsg,
GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg
: ": Transaction data rebalanced exception");
throw TransactionDataRebalancedException{message};
}
[[noreturn]] void transactionDataNodeHasDepartedException(std::string message,
std::string& exMsg,
GfErrType,
std::string) {
message.append(!exMsg.empty()
? exMsg
: ": Transaction data node has departed exception");
throw TransactionDataNodeHasDepartedException{message};
}
[[noreturn]] void putAllPartialResultException(std::string message,
std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": PutAll Partial exception");
throw PutAllPartialResultException{message};
}
[[noreturn]] void lowMemoryException(std::string message, std::string& exMsg,
GfErrType, std::string) {
message.append(!exMsg.empty() ? exMsg : ": Low memory exception");
throw LowMemoryException{message};
}
[[noreturn]] void queryLowMemoryException(std::string message,
std::string& exMsg, GfErrType,
std::string) {
message.append(!exMsg.empty() ? exMsg
: ": Query execution low memory exception");
throw QueryExecutionLowMemoryException{message};
}
[[noreturn]] void unknownException(std::string message, std::string& exMsg,
GfErrType err, std::string func) {
LOGINFO("error code: %d", err);
message = func;
if (exMsg.empty()) {
message.append("Unknown error code ").append(std::to_string(err));
} else {
message.append(exMsg);
}
throw UnknownException{message};
}
} // namespace
using error_function_t =
std::function<void(std::string, std::string&, GfErrType, std::string)>;
std::map<GfErrType, error_function_t>& get_error_map() {
static std::map<GfErrType, error_function_t> error_map{
{GF_NOTCON, notConnectedException},
{GF_MSG, messageException},
{GF_CACHESERVER_EXCEPTION, cacheServerException},
{GF_NOTOWN, notOwnerException},
{GF_CACHE_REGION_NOT_FOUND, cacheServerException},
{GF_CACHE_REGION_NOT_GLOBAL, illegalStateException},
{GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION, illegalArgumentException},
{GF_CACHE_ILLEGAL_STATE_EXCEPTION, illegalStateException},
{GF_CACHE_WRITER_EXCEPTION, cacheWriterException},
{GF_CACHEWRITER_ERROR, cacheWriterException},
{GF_CACHE_LOADER_EXCEPTION, cacheLoaderException},
{GF_CACHE_LISTENER_EXCEPTION, cacheListenerException},
{GF_CACHE_REGION_INVALID, regionDestroyedException},
{GF_CACHE_PROXY, cacheProxyException},
{GF_IOERR, geodeIOException},
{GF_ENOENT, noSystemException},
{GF_CACHE_REGION_KEYS_NOT_STRINGS, illegalArgumentException},
{GF_CACHE_REGION_ENTRY_NOT_BYTES, illegalArgumentException},
{GF_CACHE_TIMEOUT_EXCEPTION, timeoutException},
{GF_TIMEOUT, timeoutException},
{GF_CLIENT_WAIT_TIMEOUT, timeoutException},
{GF_ENOMEM, outOfMemoryException},
{GF_ERANGE, bufferSizeExceededException},
{GF_CACHE_LEASE_EXPIRED_EXCEPTION, leaseExpiredException},
{GF_CACHE_REGION_EXISTS_EXCEPTION, regionExistsException},
{GF_CACHE_ENTRY_NOT_FOUND, entryNotFoundException},
{GF_CACHE_ENTRY_EXISTS, entryExistsException},
{GF_CACHE_ENTRY_DESTROYED_EXCEPTION, entryDestroyedException},
{GF_CACHE_REGION_DESTROYED_EXCEPTION, regionDestroyedException},
{GF_CACHE_CLOSED_EXCEPTION, cacheClosedException},
{GF_CACHE_STATISTICS_DISABLED_EXCEPTION, statisticsDisabledException},
{GF_CACHE_CONCURRENT_MODIFICATION_EXCEPTION,
concurrentModificationException},
{GF_NOT_AUTHORIZED_EXCEPTION, notAuthorizedException},
{GF_AUTHENTICATION_FAILED_EXCEPTION, authenticationFailedException},
{GF_AUTHENTICATION_REQUIRED_EXCEPTION, authenticationRequiredException},
{GF_DUPLICATE_DURABLE_CLIENT, duplicateDurableClientException},
{GF_REMOTE_QUERY_EXCEPTION, queryException},
{GF_CACHE_LOCATOR_EXCEPTION, noAvailableLocatorsException},
{GF_ALL_CONNECTIONS_IN_USE_EXCEPTION, allConnectionsInUseException},
{GF_FUNCTION_EXCEPTION, functionExecutionException},
{GF_DISKFULL, diskFailureException},
{GF_ROLLBACK_EXCEPTION, rollbackException},
{GF_COMMIT_CONFLICT_EXCEPTION, commitConflictException},
{GF_TRANSACTION_DATA_REBALANCED_EXCEPTION,
transactionDataRebalancedException},
{GF_TRANSACTION_DATA_NODE_HAS_DEPARTED_EXCEPTION,
transactionDataNodeHasDepartedException},
{GF_PUTALL_PARTIAL_RESULT_EXCEPTION, putAllPartialResultException},
{GF_LOW_MEMORY_EXCEPTION, lowMemoryException},
{GF_QUERY_EXECUTION_LOW_MEMORY_EXCEPTION, queryLowMemoryException},
{GF_NOERR, unknownException},
{GF_DEADLK, unknownException},
{GF_EACCES, unknownException},
{GF_ECONFL, unknownException},
{GF_EINVAL, unknownException},
{GF_ETYPE, unknownException},
{GF_NOTOBJ, unknownException},
{GF_NOTSUP, unknownException},
{GF_SCPGBL, unknownException},
{GF_SCPEXC, unknownException},
{GF_OVRFLW, unknownException},
{GF_EINTR, unknownException},
{GF_NOSERVER_FOUND, unknownException},
{GF_SERVER_FAILED, unknownException},
{GF_CLIENT_WAIT_TIMEOUT_REFRESH_PRMETADATA, unknownException},
{GF_CANNOT_PROCESS_GII_REQUEST, unknownException},
{GF_CACHE_ENTRY_UPDATED, unknownException},
{GF_INVALID_DELTA, unknownException},
{GF_EUNDEF, unknownException}};
return error_map;
}
namespace apache {
namespace geode {
namespace client {
void setThreadLocalExceptionMessage(std::string exMsg);
const std::string& getThreadLocalExceptionMessage();
[[noreturn]] void GfErrTypeThrowException(const char* str, GfErrType err) {
std::string func;
std::string message;
auto exMsg = getThreadLocalExceptionMessage();
setThreadLocalExceptionMessage("");
if (!exMsg.empty()) {
func.append(str);
func.append(": ");
}
auto& error_map = get_error_map();
auto iter = error_map.find(err);
if (iter != std::end(error_map)) {
iter->second(message, exMsg, err, func);
}
unknownException(message, exMsg, err, func);
}
} // namespace client
} // namespace geode
} // namespace apache