From abe34a45863e3fda31438b0af889949c8369617d Mon Sep 17 00:00:00 2001 From: starlord Date: Thu, 27 Jun 2019 18:03:52 +0800 Subject: [PATCH] MS-126 Add more error code Former-commit-id: 43496ac3c9a578105131219f6802de3bec78746d --- cpp/CHANGELOG.md | 1 + cpp/src/db/DBMetaImpl.cpp | 12 +- cpp/src/server/RequestScheduler.cpp | 52 +++--- cpp/src/server/RequestScheduler.h | 2 + cpp/src/server/RequestTask.cpp | 237 +++++++++--------------- cpp/src/thrift/gen-cpp/milvus_types.cpp | 34 +++- cpp/src/thrift/gen-cpp/milvus_types.h | 26 ++- cpp/src/thrift/milvus.thrift | 14 ++ cpp/src/utils/Error.h | 41 ++-- cpp/unittest/db/meta_tests.cpp | 70 +++---- 10 files changed, 261 insertions(+), 228 deletions(-) diff --git a/cpp/CHANGELOG.md b/cpp/CHANGELOG.md index 1245b7efd..be7024672 100644 --- a/cpp/CHANGELOG.md +++ b/cpp/CHANGELOG.md @@ -23,6 +23,7 @@ Please mark all change in change log and use the ticket from JIRA. - MS-115 - Change is_startup of metric_config switch from true to on - MS-122 - Archive criteria config - MS-124 - HasTable interface +- MS-126 - Add more error code ## New Feature diff --git a/cpp/src/db/DBMetaImpl.cpp b/cpp/src/db/DBMetaImpl.cpp index 9a44820c7..8c56c863e 100644 --- a/cpp/src/db/DBMetaImpl.cpp +++ b/cpp/src/db/DBMetaImpl.cpp @@ -193,9 +193,11 @@ Status DBMetaImpl::CreateTable(TableSchema &table_schema) { auto table = ConnectorPtr->select(columns(&TableSchema::state_), where(c(&TableSchema::table_id_) == table_schema.table_id_)); if (table.size() == 1) { - std::string msg = (TableSchema::TO_DELETE == std::get<0>(table[0])) ? - "Table already exists and it is in delete state, please wait a second" : "Table already exists"; - return Status::Error(msg); + if(TableSchema::TO_DELETE == std::get<0>(table[0])) { + return Status::Error("Table already exists and it is in delete state, please wait a second"); + } else { + return Status::OK();//table already exists, no error + } } } @@ -329,7 +331,7 @@ Status DBMetaImpl::HasTable(const std::string &table_id, bool &has_or_not) { } } catch (std::exception &e) { - HandleException("Encounter exception when lookup table", e); + return HandleException("Encounter exception when lookup table", e); } return Status::OK(); @@ -359,7 +361,7 @@ Status DBMetaImpl::AllTables(std::vector& table_schema_array) { } } catch (std::exception &e) { - HandleException("Encounter exception when lookup all tables", e); + return HandleException("Encounter exception when lookup all tables", e); } return Status::OK(); diff --git a/cpp/src/server/RequestScheduler.cpp b/cpp/src/server/RequestScheduler.cpp index 99ae36701..36df155b6 100644 --- a/cpp/src/server/RequestScheduler.cpp +++ b/cpp/src/server/RequestScheduler.cpp @@ -18,34 +18,34 @@ using namespace ::milvus; namespace { const std::map &ErrorMap() { static const std::map code_map = { - {SERVER_UNEXPECTED_ERROR, thrift::ErrorCode::ILLEGAL_ARGUMENT}, - {SERVER_NULL_POINTER, thrift::ErrorCode::ILLEGAL_ARGUMENT}, + {SERVER_UNEXPECTED_ERROR, thrift::ErrorCode::UNEXPECTED_ERROR}, + {SERVER_UNSUPPORTED_ERROR, thrift::ErrorCode::UNEXPECTED_ERROR}, + {SERVER_NULL_POINTER, thrift::ErrorCode::UNEXPECTED_ERROR}, {SERVER_INVALID_ARGUMENT, thrift::ErrorCode::ILLEGAL_ARGUMENT}, - {SERVER_FILE_NOT_FOUND, thrift::ErrorCode::ILLEGAL_ARGUMENT}, - {SERVER_NOT_IMPLEMENT, thrift::ErrorCode::ILLEGAL_ARGUMENT}, - {SERVER_BLOCKING_QUEUE_EMPTY, thrift::ErrorCode::ILLEGAL_ARGUMENT}, + {SERVER_FILE_NOT_FOUND, thrift::ErrorCode::FILE_NOT_FOUND}, + {SERVER_NOT_IMPLEMENT, thrift::ErrorCode::UNEXPECTED_ERROR}, + {SERVER_BLOCKING_QUEUE_EMPTY, thrift::ErrorCode::UNEXPECTED_ERROR}, + {SERVER_CANNOT_CREATE_FOLDER, thrift::ErrorCode::CANNOT_CREATE_FOLDER}, + {SERVER_CANNOT_CREATE_FILE, thrift::ErrorCode::CANNOT_CREATE_FILE}, + {SERVER_CANNOT_DELETE_FOLDER, thrift::ErrorCode::CANNOT_DELETE_FOLDER}, + {SERVER_CANNOT_DELETE_FILE, thrift::ErrorCode::CANNOT_DELETE_FILE}, {SERVER_TABLE_NOT_EXIST, thrift::ErrorCode::TABLE_NOT_EXISTS}, + {SERVER_INVALID_TABLE_NAME, thrift::ErrorCode::ILLEGAL_TABLE_NAME}, + {SERVER_INVALID_TABLE_DIMENSION, thrift::ErrorCode::ILLEGAL_DIMENSION}, {SERVER_INVALID_TIME_RANGE, thrift::ErrorCode::ILLEGAL_RANGE}, {SERVER_INVALID_VECTOR_DIMENSION, thrift::ErrorCode::ILLEGAL_DIMENSION}, - }; - return code_map; - } - - const std::map &ErrorMessage() { - static const std::map msg_map = { - {SERVER_UNEXPECTED_ERROR, "unexpected error occurs"}, - {SERVER_NULL_POINTER, "null pointer error"}, - {SERVER_INVALID_ARGUMENT, "invalid argument"}, - {SERVER_FILE_NOT_FOUND, "file not found"}, - {SERVER_NOT_IMPLEMENT, "not implemented"}, - {SERVER_BLOCKING_QUEUE_EMPTY, "queue empty"}, - {SERVER_TABLE_NOT_EXIST, "table not exist"}, - {SERVER_INVALID_TIME_RANGE, "invalid time range"}, - {SERVER_INVALID_VECTOR_DIMENSION, "invalid vector dimension"}, + {SERVER_INVALID_INDEX_TYPE, thrift::ErrorCode::ILLEGAL_INDEX_TYPE}, + {SERVER_INVALID_ROWRECORD, thrift::ErrorCode::ILLEGAL_ROWRECORD}, + {SERVER_INVALID_ROWRECORD_ARRAY, thrift::ErrorCode::ILLEGAL_ROWRECORD}, + {SERVER_INVALID_TOPK, thrift::ErrorCode::ILLEGAL_TOPK}, + {SERVER_ILLEGAL_VECTOR_ID, thrift::ErrorCode::ILLEGAL_VECTOR_ID}, + {SERVER_ILLEGAL_SEARCH_RESULT, thrift::ErrorCode::ILLEGAL_SEARCH_RESULT}, + {SERVER_CACHE_ERROR, thrift::ErrorCode::CACHE_FAILED}, + {DB_META_TRANSACTION_FAILED, thrift::ErrorCode::META_FAILED}, }; - return msg_map; + return code_map; } } @@ -69,6 +69,14 @@ ServerError BaseTask::Execute() { return error_code_; } +ServerError BaseTask::SetError(ServerError error_code, const std::string& error_msg) { + error_code_ = error_code; + error_msg_ = error_msg; + + SERVER_LOG_ERROR << error_msg_; + return error_code_; +} + ServerError BaseTask::WaitToFinish() { std::unique_lock lock(finish_mtx_); finish_cond_.wait(lock, [this] { return done_; }); @@ -102,7 +110,7 @@ void RequestScheduler::ExecTask(BaseTaskPtr& task_ptr) { ex.__set_code(ErrorMap().at(err)); std::string msg = task_ptr->ErrorMsg(); if(msg.empty()){ - msg = ErrorMessage().at(err); + msg = "Error message not set"; } ex.__set_reason(msg); throw ex; diff --git a/cpp/src/server/RequestScheduler.h b/cpp/src/server/RequestScheduler.h index b7562cc36..d4b1e1c82 100644 --- a/cpp/src/server/RequestScheduler.h +++ b/cpp/src/server/RequestScheduler.h @@ -34,6 +34,8 @@ public: protected: virtual ServerError OnExecute() = 0; + ServerError SetError(ServerError error_code, const std::string& msg); + protected: mutable std::mutex finish_mtx_; std::condition_variable finish_cond_; diff --git a/cpp/src/server/RequestTask.cpp b/cpp/src/server/RequestTask.cpp index a4733425e..bb0c43721 100644 --- a/cpp/src/server/RequestTask.cpp +++ b/cpp/src/server/RequestTask.cpp @@ -53,26 +53,27 @@ namespace { return map_type[type]; } - ServerError + void ConvertRowRecordToFloatArray(const std::vector& record_array, uint64_t dimension, - std::vector& float_array) { - ServerError error_code; + std::vector& float_array, + ServerError& error_code, + std::string& error_msg) { uint64_t vec_count = record_array.size(); float_array.resize(vec_count*dimension);//allocate enough memory for(uint64_t i = 0; i < vec_count; i++) { const auto& record = record_array[i]; if(record.vector_data.empty()) { - error_code = SERVER_INVALID_ARGUMENT; - SERVER_LOG_ERROR << "No vector provided in record"; - return error_code; + error_code = SERVER_INVALID_ROWRECORD; + error_msg = "Rowrecord float array is empty"; + return; } uint64_t vec_dim = record.vector_data.size()/sizeof(double);//how many double value? if(vec_dim != dimension) { - SERVER_LOG_ERROR << "Invalid vector dimension: " << vec_dim - << " vs. table dimension:" << dimension; error_code = SERVER_INVALID_VECTOR_DIMENSION; - return error_code; + error_msg = "Invalid rowrecord dimension: " + std::to_string(vec_dim) + + " vs. table dimension:" + std::to_string(dimension); + return; } //convert double array to float array(thrift has no float type) @@ -81,30 +82,29 @@ namespace { float_array[i*vec_dim + d] = (float)(d_p[d]); } } - - return SERVER_SUCCESS; } static constexpr long DAY_SECONDS = 86400; - ServerError + void ConvertTimeRangeToDBDates(const std::vector &range_array, - std::vector& dates) { + std::vector& dates, + ServerError& error_code, + std::string& error_msg) { dates.clear(); - ServerError error_code; for(auto& range : range_array) { time_t tt_start, tt_end; tm tm_start, tm_end; if(!CommonUtil::TimeStrToTime(range.start_value, tt_start, tm_start)){ error_code = SERVER_INVALID_TIME_RANGE; - SERVER_LOG_ERROR << "Invalid time range: " << range.start_value; - return error_code; + error_msg = "Invalid time range: " + range.start_value; + return; } if(!CommonUtil::TimeStrToTime(range.end_value, tt_end, tm_end)){ error_code = SERVER_INVALID_TIME_RANGE; - SERVER_LOG_ERROR << "Invalid time range: " << range.end_value; - return error_code; + error_msg = "Invalid time range: " + range.start_value; + return; } long days = (tt_end > tt_start) ? (tt_end - tt_start)/DAY_SECONDS : (tt_start - tt_end)/DAY_SECONDS; @@ -117,8 +117,6 @@ namespace { dates.push_back(date); } } - - return SERVER_SUCCESS; } } @@ -138,21 +136,16 @@ ServerError CreateTableTask::OnExecute() { try { //step 1: check arguments - if(schema_.table_name.empty() || schema_.dimension <= 0) { - error_code_ = SERVER_INVALID_ARGUMENT; -// error_msg_ = schema_.table_name.empty() ? - error_msg_ = "CreateTableTask: Invalid table name or dimension. table name = " + schema_.table_name - + "dimension = " + std::to_string(schema_.dimension); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + if(schema_.table_name.empty()) { + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); + } + if(schema_.dimension <= 0) { + return SetError(SERVER_INVALID_TABLE_DIMENSION, "Invalid table dimension: " + std::to_string(schema_.dimension)); } engine::EngineType engine_type = EngineType(schema_.index_type); if(engine_type == engine::EngineType::INVALID) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "CreateTableTask: Invalid index type. type = " + std::to_string(schema_.index_type); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_INDEX_TYPE, "Invalid index type: " + std::to_string(schema_.index_type)); } //step 2: construct table schema @@ -165,17 +158,11 @@ ServerError CreateTableTask::OnExecute() { //step 3: create table engine::Status stat = DBWrapper::DB()->CreateTable(table_info); if(!stat.ok()) {//table could exist - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = "CreateTableTask: Engine failed: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); } } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << "CreateTableTask: " << error_msg_; - return error_code_; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } rc.Record("done"); @@ -201,10 +188,7 @@ ServerError DescribeTableTask::OnExecute() { try { //step 1: check arguments if(table_name_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "DescribeTableTask: Table name cannot be empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); } //step 2: get table info @@ -212,10 +196,7 @@ ServerError DescribeTableTask::OnExecute() { table_info.table_id_ = table_name_; engine::Status stat = DBWrapper::DB()->DescribeTable(table_info); if(!stat.ok()) { - error_code_ = SERVER_TABLE_NOT_EXIST; - error_msg_ = "DescribeTableTask: Engine failed: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); } schema_.table_name = table_info.table_id_; @@ -224,10 +205,7 @@ ServerError DescribeTableTask::OnExecute() { schema_.store_raw_vector = table_info.store_raw_data_; } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << "DescribeTableTask: " << error_msg_; - return SERVER_UNEXPECTED_ERROR; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } rc.Record("done"); @@ -252,22 +230,19 @@ ServerError HasTableTask::OnExecute() { TimeRecorder rc("HasTableTask"); //step 1: check arguments - if (table_name_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "Table name cannot be empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + if(table_name_.empty()) { + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); } //step 2: check table existence engine::Status stat = DBWrapper::DB()->HasTable(table_name_, has_table_); + if(!stat.ok()) { + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); + } rc.Elapse("totally cost"); } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } return SERVER_SUCCESS; @@ -290,10 +265,7 @@ ServerError DeleteTableTask::OnExecute() { //step 1: check arguments if (table_name_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "DeleteTableTask: Table name cannot be empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); } //step 2: check table existence @@ -301,10 +273,11 @@ ServerError DeleteTableTask::OnExecute() { table_info.table_id_ = table_name_; engine::Status stat = DBWrapper::DB()->DescribeTable(table_info); if(!stat.ok()) { - error_code_ = SERVER_TABLE_NOT_EXIST; - error_msg_ = "DeleteTableTask: Engine failed: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + if(stat.IsNotFound()) { + return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name_ + " not exists"); + } else { + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); + } } rc.Record("check validation"); @@ -313,17 +286,13 @@ ServerError DeleteTableTask::OnExecute() { std::vector dates; stat = DBWrapper::DB()->DeleteTable(table_name_, dates); if(!stat.ok()) { - SERVER_LOG_ERROR << "DeleteTableTask: Engine failed: " << stat.ToString(); - return SERVER_UNEXPECTED_ERROR; + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); } rc.Record("deleta table"); rc.Elapse("total cost"); } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << "DeleteTableTask: " << error_msg_; - return error_code_; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } return SERVER_SUCCESS; @@ -344,10 +313,7 @@ ServerError ShowTablesTask::OnExecute() { std::vector schema_array; engine::Status stat = DBWrapper::DB()->AllTables(schema_array); if(!stat.ok()) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = "ShowTablesTask: Engine failed: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); } tables_.clear(); @@ -381,17 +347,11 @@ ServerError AddVectorTask::OnExecute() { //step 1: check arguments if (table_name_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "AddVectorTask: Table name cannot be empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); } if(record_array_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "AddVectorTask: Row record array is empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_ROWRECORD_ARRAY, "Row record array is empty"); } //step 2: check table existence @@ -399,20 +359,22 @@ ServerError AddVectorTask::OnExecute() { table_info.table_id_ = table_name_; engine::Status stat = DBWrapper::DB()->DescribeTable(table_info); if(!stat.ok()) { - error_code_ = SERVER_TABLE_NOT_EXIST; - error_msg_ = "AddVectorTask: Engine failed when DescribeTable: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + if(stat.IsNotFound()) { + return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name_ + " not exists"); + } else { + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); + } } rc.Record("check validation"); //step 3: prepare float data std::vector vec_f; - error_code_ = ConvertRowRecordToFloatArray(record_array_, table_info.dimension_, vec_f); - if(error_code_ != SERVER_SUCCESS) { - error_msg_ = "AddVectorTask when ConvertRowRecordToFloatArray: Invalid row record data"; - return error_code_; + ServerError error_code = SERVER_SUCCESS; + std::string error_msg; + ConvertRowRecordToFloatArray(record_array_, table_info.dimension_, vec_f, error_code, error_msg); + if(error_code != SERVER_SUCCESS) { + return SetError(error_code, error_msg); } rc.Record("prepare vectors data"); @@ -422,25 +384,20 @@ ServerError AddVectorTask::OnExecute() { stat = DBWrapper::DB()->InsertVectors(table_name_, vec_count, vec_f.data(), record_ids_); rc.Record("add vectors to engine"); if(!stat.ok()) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = "AddVectorTask: Engine failed when InsertVectors: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_CACHE_ERROR, "Cache error: " + stat.ToString()); } if(record_ids_.size() != vec_count) { - SERVER_LOG_ERROR << "AddVectorTask: Vector ID not returned"; - return SERVER_UNEXPECTED_ERROR; + std::string msg = "Add " + std::to_string(vec_count) + " vectors but only return " + + std::to_string(record_ids_.size()) + " id"; + return SetError(SERVER_ILLEGAL_VECTOR_ID, msg); } rc.Record("do insert"); rc.Elapse("total cost"); } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << "AddVectorTask: " << error_msg_; - return error_code_; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } return SERVER_SUCCESS; @@ -479,17 +436,14 @@ ServerError SearchVectorTask::OnExecute() { //step 1: check arguments if (table_name_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "SearchVectorTask: Table name cannot be empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); } - if(top_k_ <= 0 || record_array_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "SearchVectorTask: Invalid topk value, or query record array is empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + if(top_k_ <= 0) { + return SetError(SERVER_INVALID_TOPK, "Invalid topk: " + std::to_string(top_k_)); + } + if(record_array_.empty()) { + return SetError(SERVER_INVALID_ROWRECORD_ARRAY, "Row record array is empty"); } //step 2: check table existence @@ -497,28 +451,29 @@ ServerError SearchVectorTask::OnExecute() { table_info.table_id_ = table_name_; engine::Status stat = DBWrapper::DB()->DescribeTable(table_info); if(!stat.ok()) { - error_code_ = SERVER_TABLE_NOT_EXIST; - error_msg_ = "SearchVectorTask: Engine failed when DescribeTable: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + if(stat.IsNotFound()) { + return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name_ + " not exists"); + } else { + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); + } } //step 3: check date range, and convert to db dates std::vector dates; - error_code_ = ConvertTimeRangeToDBDates(range_array_, dates); - if(error_code_ != SERVER_SUCCESS) { - error_msg_ = "SearchVectorTask: Invalid query range when ConvertTimeRangeToDBDates"; - return error_code_; + ServerError error_code = SERVER_SUCCESS; + std::string error_msg; + ConvertTimeRangeToDBDates(range_array_, dates, error_code, error_msg); + if(error_code != SERVER_SUCCESS) { + return SetError(error_code, error_msg); } rc.Record("check validation"); //step 3: prepare float data std::vector vec_f; - error_code_ = ConvertRowRecordToFloatArray(record_array_, table_info.dimension_, vec_f); - if(error_code_ != SERVER_SUCCESS) { - error_msg_ = "Invalid row record data when ConvertRowRecordToFloatArray"; - return error_code_; + ConvertRowRecordToFloatArray(record_array_, table_info.dimension_, vec_f, error_code, error_msg); + if(error_code != SERVER_SUCCESS) { + return SetError(error_code, error_msg); } rc.Record("prepare vector data"); @@ -535,13 +490,17 @@ ServerError SearchVectorTask::OnExecute() { rc.Record("search vectors from engine"); if(!stat.ok()) { - SERVER_LOG_ERROR << "SearchVectorTask: Engine failed: " << stat.ToString(); - return SERVER_UNEXPECTED_ERROR; + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); + } + + if(results.empty()) { + return SERVER_SUCCESS; //empty table } if(results.size() != record_count) { - SERVER_LOG_ERROR << "SearchVectorTask: Search result not returned"; - return SERVER_UNEXPECTED_ERROR; + std::string msg = "Search " + std::to_string(record_count) + " vectors but only return " + + std::to_string(results.size()) + " results"; + return SetError(SERVER_ILLEGAL_SEARCH_RESULT, msg); } rc.Record("do search"); @@ -566,10 +525,7 @@ ServerError SearchVectorTask::OnExecute() { rc.Elapse("total cost"); } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << "SearchVectorTask: " << error_msg_; - return error_code_; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } return SERVER_SUCCESS; @@ -593,20 +549,14 @@ ServerError GetTableRowCountTask::OnExecute() { //step 1: check arguments if (table_name_.empty()) { - error_code_ = SERVER_INVALID_ARGUMENT; - error_msg_ = "GetTableRowCountTask: Table name cannot be empty"; - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(SERVER_INVALID_TABLE_NAME, "Empty table name"); } //step 2: get row count uint64_t row_count = 0; engine::Status stat = DBWrapper::DB()->GetTableRowCount(table_name_, row_count); if (!stat.ok()) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = "GetTableRowCountTask: Engine failed: " + stat.ToString(); - SERVER_LOG_ERROR << error_msg_; - return error_code_; + return SetError(DB_META_TRANSACTION_FAILED, "Engine failed: " + stat.ToString()); } row_count_ = (int64_t) row_count; @@ -614,10 +564,7 @@ ServerError GetTableRowCountTask::OnExecute() { rc.Elapse("total cost"); } catch (std::exception& ex) { - error_code_ = SERVER_UNEXPECTED_ERROR; - error_msg_ = ex.what(); - SERVER_LOG_ERROR << "GetTableRowCountTask: " << error_msg_; - return error_code_; + return SetError(SERVER_UNEXPECTED_ERROR, ex.what()); } return SERVER_SUCCESS; diff --git a/cpp/src/thrift/gen-cpp/milvus_types.cpp b/cpp/src/thrift/gen-cpp/milvus_types.cpp index 203faa2e5..af77fda0a 100644 --- a/cpp/src/thrift/gen-cpp/milvus_types.cpp +++ b/cpp/src/thrift/gen-cpp/milvus_types.cpp @@ -15,23 +15,51 @@ namespace milvus { namespace thrift { int _kErrorCodeValues[] = { ErrorCode::SUCCESS, + ErrorCode::UNEXPECTED_ERROR, ErrorCode::CONNECT_FAILED, ErrorCode::PERMISSION_DENIED, ErrorCode::TABLE_NOT_EXISTS, ErrorCode::ILLEGAL_ARGUMENT, ErrorCode::ILLEGAL_RANGE, - ErrorCode::ILLEGAL_DIMENSION + ErrorCode::ILLEGAL_DIMENSION, + ErrorCode::ILLEGAL_INDEX_TYPE, + ErrorCode::ILLEGAL_TABLE_NAME, + ErrorCode::ILLEGAL_TOPK, + ErrorCode::ILLEGAL_ROWRECORD, + ErrorCode::ILLEGAL_VECTOR_ID, + ErrorCode::ILLEGAL_SEARCH_RESULT, + ErrorCode::FILE_NOT_FOUND, + ErrorCode::META_FAILED, + ErrorCode::CACHE_FAILED, + ErrorCode::CANNOT_CREATE_FOLDER, + ErrorCode::CANNOT_CREATE_FILE, + ErrorCode::CANNOT_DELETE_FOLDER, + ErrorCode::CANNOT_DELETE_FILE }; const char* _kErrorCodeNames[] = { "SUCCESS", + "UNEXPECTED_ERROR", "CONNECT_FAILED", "PERMISSION_DENIED", "TABLE_NOT_EXISTS", "ILLEGAL_ARGUMENT", "ILLEGAL_RANGE", - "ILLEGAL_DIMENSION" + "ILLEGAL_DIMENSION", + "ILLEGAL_INDEX_TYPE", + "ILLEGAL_TABLE_NAME", + "ILLEGAL_TOPK", + "ILLEGAL_ROWRECORD", + "ILLEGAL_VECTOR_ID", + "ILLEGAL_SEARCH_RESULT", + "FILE_NOT_FOUND", + "META_FAILED", + "CACHE_FAILED", + "CANNOT_CREATE_FOLDER", + "CANNOT_CREATE_FILE", + "CANNOT_DELETE_FOLDER", + "CANNOT_DELETE_FILE" }; -const std::map _ErrorCode_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(7, _kErrorCodeValues, _kErrorCodeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); +const std::map _ErrorCode_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(21, _kErrorCodeValues, _kErrorCodeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL)); std::ostream& operator<<(std::ostream& out, const ErrorCode::type& val) { std::map::const_iterator it = _ErrorCode_VALUES_TO_NAMES.find(val); diff --git a/cpp/src/thrift/gen-cpp/milvus_types.h b/cpp/src/thrift/gen-cpp/milvus_types.h index ea4178aa9..8840e94fd 100644 --- a/cpp/src/thrift/gen-cpp/milvus_types.h +++ b/cpp/src/thrift/gen-cpp/milvus_types.h @@ -23,12 +23,26 @@ namespace milvus { namespace thrift { struct ErrorCode { enum type { SUCCESS = 0, - CONNECT_FAILED = 1, - PERMISSION_DENIED = 2, - TABLE_NOT_EXISTS = 3, - ILLEGAL_ARGUMENT = 4, - ILLEGAL_RANGE = 5, - ILLEGAL_DIMENSION = 6 + UNEXPECTED_ERROR = 1, + CONNECT_FAILED = 2, + PERMISSION_DENIED = 3, + TABLE_NOT_EXISTS = 4, + ILLEGAL_ARGUMENT = 5, + ILLEGAL_RANGE = 6, + ILLEGAL_DIMENSION = 7, + ILLEGAL_INDEX_TYPE = 8, + ILLEGAL_TABLE_NAME = 9, + ILLEGAL_TOPK = 10, + ILLEGAL_ROWRECORD = 11, + ILLEGAL_VECTOR_ID = 12, + ILLEGAL_SEARCH_RESULT = 13, + FILE_NOT_FOUND = 14, + META_FAILED = 15, + CACHE_FAILED = 16, + CANNOT_CREATE_FOLDER = 17, + CANNOT_CREATE_FILE = 18, + CANNOT_DELETE_FOLDER = 19, + CANNOT_DELETE_FILE = 20 }; }; diff --git a/cpp/src/thrift/milvus.thrift b/cpp/src/thrift/milvus.thrift index 48116256e..88ba223f0 100644 --- a/cpp/src/thrift/milvus.thrift +++ b/cpp/src/thrift/milvus.thrift @@ -15,12 +15,26 @@ namespace netcore milvus.thrift enum ErrorCode { SUCCESS = 0, + UNEXPECTED_ERROR, CONNECT_FAILED, PERMISSION_DENIED, TABLE_NOT_EXISTS, ILLEGAL_ARGUMENT, ILLEGAL_RANGE, ILLEGAL_DIMENSION, + ILLEGAL_INDEX_TYPE, + ILLEGAL_TABLE_NAME, + ILLEGAL_TOPK, + ILLEGAL_ROWRECORD, + ILLEGAL_VECTOR_ID, + ILLEGAL_SEARCH_RESULT, + FILE_NOT_FOUND, + META_FAILED, + CACHE_FAILED, + CANNOT_CREATE_FOLDER, + CANNOT_CREATE_FILE, + CANNOT_DELETE_FOLDER, + CANNOT_DELETE_FILE, } exception Exception { diff --git a/cpp/src/utils/Error.h b/cpp/src/utils/Error.h index bfb19f47a..8c4da7033 100644 --- a/cpp/src/utils/Error.h +++ b/cpp/src/utils/Error.h @@ -24,18 +24,35 @@ ToGlobalServerErrorCode(const ServerError error_code) { return SERVER_ERROR_CODE_BASE + error_code; } -constexpr ServerError SERVER_UNEXPECTED_ERROR = ToGlobalServerErrorCode(0x001); -constexpr ServerError SERVER_UNSUPPORTED_ERROR = ToGlobalServerErrorCode(0x002); -constexpr ServerError SERVER_NULL_POINTER = ToGlobalServerErrorCode(0x003); -constexpr ServerError SERVER_INVALID_ARGUMENT = ToGlobalServerErrorCode(0x004); -constexpr ServerError SERVER_FILE_NOT_FOUND = ToGlobalServerErrorCode(0x005); -constexpr ServerError SERVER_NOT_IMPLEMENT = ToGlobalServerErrorCode(0x006); -constexpr ServerError SERVER_BLOCKING_QUEUE_EMPTY = ToGlobalServerErrorCode(0x007); -constexpr ServerError SERVER_TABLE_NOT_EXIST = ToGlobalServerErrorCode(0x008); -constexpr ServerError SERVER_INVALID_TIME_RANGE = ToGlobalServerErrorCode(0x009); -constexpr ServerError SERVER_INVALID_VECTOR_DIMENSION = ToGlobalServerErrorCode(0x00a); -constexpr ServerError SERVER_LICENSE_VALIDATION_FAIL = ToGlobalServerErrorCode(0x00b); -constexpr ServerError SERVER_LICENSE_FILE_NOT_EXIST = ToGlobalServerErrorCode(0x00c); +constexpr ServerError SERVER_UNEXPECTED_ERROR = ToGlobalServerErrorCode(1); +constexpr ServerError SERVER_UNSUPPORTED_ERROR = ToGlobalServerErrorCode(2); +constexpr ServerError SERVER_NULL_POINTER = ToGlobalServerErrorCode(3); +constexpr ServerError SERVER_INVALID_ARGUMENT = ToGlobalServerErrorCode(4); +constexpr ServerError SERVER_FILE_NOT_FOUND = ToGlobalServerErrorCode(5); +constexpr ServerError SERVER_NOT_IMPLEMENT = ToGlobalServerErrorCode(6); +constexpr ServerError SERVER_BLOCKING_QUEUE_EMPTY = ToGlobalServerErrorCode(7); +constexpr ServerError SERVER_CANNOT_CREATE_FOLDER = ToGlobalServerErrorCode(8); +constexpr ServerError SERVER_CANNOT_CREATE_FILE = ToGlobalServerErrorCode(9); +constexpr ServerError SERVER_CANNOT_DELETE_FOLDER = ToGlobalServerErrorCode(10); +constexpr ServerError SERVER_CANNOT_DELETE_FILE = ToGlobalServerErrorCode(11); + +constexpr ServerError SERVER_TABLE_NOT_EXIST = ToGlobalServerErrorCode(100); +constexpr ServerError SERVER_INVALID_TABLE_NAME = ToGlobalServerErrorCode(101); +constexpr ServerError SERVER_INVALID_TABLE_DIMENSION = ToGlobalServerErrorCode(102); +constexpr ServerError SERVER_INVALID_TIME_RANGE = ToGlobalServerErrorCode(103); +constexpr ServerError SERVER_INVALID_VECTOR_DIMENSION = ToGlobalServerErrorCode(104); +constexpr ServerError SERVER_INVALID_INDEX_TYPE = ToGlobalServerErrorCode(105); +constexpr ServerError SERVER_INVALID_ROWRECORD = ToGlobalServerErrorCode(106); +constexpr ServerError SERVER_INVALID_ROWRECORD_ARRAY = ToGlobalServerErrorCode(107); +constexpr ServerError SERVER_INVALID_TOPK = ToGlobalServerErrorCode(108); +constexpr ServerError SERVER_ILLEGAL_VECTOR_ID = ToGlobalServerErrorCode(109); +constexpr ServerError SERVER_ILLEGAL_SEARCH_RESULT = ToGlobalServerErrorCode(110); +constexpr ServerError SERVER_CACHE_ERROR = ToGlobalServerErrorCode(111); + +constexpr ServerError SERVER_LICENSE_FILE_NOT_EXIST = ToGlobalServerErrorCode(500); +constexpr ServerError SERVER_LICENSE_VALIDATION_FAIL = ToGlobalServerErrorCode(501); + +constexpr ServerError DB_META_TRANSACTION_FAILED = ToGlobalServerErrorCode(1000); class ServerException : public std::exception { public: diff --git a/cpp/unittest/db/meta_tests.cpp b/cpp/unittest/db/meta_tests.cpp index 7bc9db090..a7933829c 100644 --- a/cpp/unittest/db/meta_tests.cpp +++ b/cpp/unittest/db/meta_tests.cpp @@ -17,39 +17,39 @@ using namespace zilliz::milvus::engine; -TEST_F(MetaTest, GROUP_TEST) { - auto table_id = "meta_test_group"; +TEST_F(MetaTest, TABLE_TEST) { + auto table_id = "meta_test_table"; - meta::TableSchema group; - group.table_id_ = table_id; - auto status = impl_->CreateTable(group); + meta::TableSchema table; + table.table_id_ = table_id; + auto status = impl_->CreateTable(table); ASSERT_TRUE(status.ok()); - auto gid = group.id_; - group.id_ = -1; - status = impl_->DescribeTable(group); + auto gid = table.id_; + table.id_ = -1; + status = impl_->DescribeTable(table); ASSERT_TRUE(status.ok()); - ASSERT_EQ(group.id_, gid); - ASSERT_EQ(group.table_id_, table_id); + ASSERT_EQ(table.id_, gid); + ASSERT_EQ(table.table_id_, table_id); - group.table_id_ = "not_found"; - status = impl_->DescribeTable(group); + table.table_id_ = "not_found"; + status = impl_->DescribeTable(table); ASSERT_TRUE(!status.ok()); - group.table_id_ = table_id; - status = impl_->CreateTable(group); - ASSERT_TRUE(!status.ok()); + table.table_id_ = table_id; + status = impl_->CreateTable(table); + ASSERT_TRUE(status.ok()); } -TEST_F(MetaTest, table_file_TEST) { - auto table_id = "meta_test_group"; +TEST_F(MetaTest, TABLE_FILE_TEST) { + auto table_id = "meta_test_table"; - meta::TableSchema group; - group.table_id_ = table_id; - auto status = impl_->CreateTable(group); + meta::TableSchema table; + table.table_id_ = table_id; + auto status = impl_->CreateTable(table); meta::TableFileSchema table_file; - table_file.table_id_ = group.table_id_; + table_file.table_id_ = table.table_id_; status = impl_->CreateTableFile(table_file); ASSERT_TRUE(status.ok()); ASSERT_EQ(table_file.file_type_, meta::TableFileSchema::NEW); @@ -104,15 +104,15 @@ TEST_F(MetaTest, ARCHIVE_TEST_DAYS) { options.archive_conf = ArchiveConf("delete", ss.str()); auto impl = meta::DBMetaImpl(options); - auto table_id = "meta_test_group"; + auto table_id = "meta_test_table"; - meta::TableSchema group; - group.table_id_ = table_id; - auto status = impl.CreateTable(group); + meta::TableSchema table; + table.table_id_ = table_id; + auto status = impl.CreateTable(table); meta::TableFilesSchema files; meta::TableFileSchema table_file; - table_file.table_id_ = group.table_id_; + table_file.table_id_ = table.table_id_; auto cnt = 100; long ts = utils::GetMicroSecTimeStamp(); @@ -156,13 +156,13 @@ TEST_F(MetaTest, ARCHIVE_TEST_DISK) { auto impl = meta::DBMetaImpl(options); auto table_id = "meta_test_group"; - meta::TableSchema group; - group.table_id_ = table_id; - auto status = impl.CreateTable(group); + meta::TableSchema table; + table.table_id_ = table_id; + auto status = impl.CreateTable(table); meta::TableFilesSchema files; meta::TableFileSchema table_file; - table_file.table_id_ = group.table_id_; + table_file.table_id_ = table.table_id_; auto cnt = 10; auto each_size = 2UL; @@ -198,9 +198,9 @@ TEST_F(MetaTest, ARCHIVE_TEST_DISK) { TEST_F(MetaTest, TABLE_FILES_TEST) { auto table_id = "meta_test_group"; - meta::TableSchema group; - group.table_id_ = table_id; - auto status = impl_->CreateTable(group); + meta::TableSchema table; + table.table_id_ = table_id; + auto status = impl_->CreateTable(table); int new_files_cnt = 4; int raw_files_cnt = 5; @@ -208,7 +208,7 @@ TEST_F(MetaTest, TABLE_FILES_TEST) { int index_files_cnt = 7; meta::TableFileSchema table_file; - table_file.table_id_ = group.table_id_; + table_file.table_id_ = table.table_id_; for (auto i=0; iCreateTableFile(table_file); @@ -241,7 +241,7 @@ TEST_F(MetaTest, TABLE_FILES_TEST) { ASSERT_EQ(files.size(), to_index_files_cnt); meta::DatePartionedTableFilesSchema dated_files; - status = impl_->FilesToMerge(group.table_id_, dated_files); + status = impl_->FilesToMerge(table.table_id_, dated_files); ASSERT_TRUE(status.ok()); ASSERT_EQ(dated_files[table_file.date_].size(), raw_files_cnt); -- GitLab