Commit af7814e2 authored by Christophe Gonzales's avatar Christophe Gonzales

improved messages in exceptions raised by learning database-related classes

parent 4854161f
Pipeline #23749669 canceled with stages
in 40 seconds
......@@ -223,6 +223,34 @@ namespace gum {
return false;
}
// raises an appropriate exception when encountering a type error
std::string DBCell::__typeErrorMsg ( const std::string& true_type ) const {
std::stringstream str;
switch ( __type ) {
case EltType::REAL:
str << "The DBCell contains a real number instead of " << true_type;
break;
case EltType::INTEGER:
str << "The DBCell contains an integer instead of " << true_type;
break;
case EltType::STRING:
str << "The DBCell contains a string instead of " << true_type;
break;
case EltType::MISSING:
str << "The DBCell contains a missing value instead of " << true_type;
break;
default:
GUM_ERROR(NotImplementedYet, "DBCell type not implemented yet");
}
return str.str ();
}
} /* namespace learning */
} /* namespace gum */
......
......@@ -272,11 +272,13 @@ namespace gum {
using UnionType =
typename std::conditional< sizeof(int) < sizeof(float), float, int >::type;
// raises an appropriate exception when encountering a type error
std::string __typeErrorMsg ( const std::string& real_type ) const;
// a bijection assigning to each string index its corresponding string
static Bijection< std::string, int >& __strings();
// the last index used so far
static int __string_max_index;
......
......@@ -157,13 +157,13 @@ namespace gum {
/// returns the current type of the DBCell
INLINE DBCell::EltType DBCell::type() const noexcept { return __type; }
/// returns the DBcell as a float
INLINE float DBCell::real() const {
if (__type == EltType::REAL)
return __val_real;
else
GUM_ERROR(TypeError, "the DBCell does not contain a real number");
GUM_ERROR(TypeError, __typeErrorMsg ("a real number") );
}
......@@ -188,7 +188,7 @@ namespace gum {
if (__type == EltType::INTEGER)
return __val_integer;
else
GUM_ERROR(TypeError, "the DBCell does not contain an integer");
GUM_ERROR(TypeError, __typeErrorMsg ("an integer") );
}
......@@ -213,7 +213,7 @@ namespace gum {
if (__type == EltType::STRING)
return __strings().first(__val_index);
else
GUM_ERROR(TypeError, "the DBCell does not contain a string");
GUM_ERROR(TypeError, __typeErrorMsg ("a string") );
}
......@@ -222,7 +222,7 @@ namespace gum {
if (__type == EltType::STRING)
return __val_index;
else
GUM_ERROR(TypeError, "the DBCell does not contain a string");
GUM_ERROR(TypeError, __typeErrorMsg ("a string") );
}
......
......@@ -55,31 +55,43 @@ namespace gum {
deb_index = connection_string.find(delimiter, 0);
if (deb_index == std::string::npos)
GUM_ERROR(DatabaseError, "could not determine the datasource");
GUM_ERROR(DatabaseError,
"could not determine the datasource from string " <<
connection_string);
deb_index += std::size_t(1);
end_index = connection_string.find(delimiter, deb_index);
if (end_index == std::string::npos)
GUM_ERROR(DatabaseError, "could not determine the datasource");
GUM_ERROR(DatabaseError,
"could not determine the datasource from string " <<
connection_string);
std::string dataSource =
connection_string.substr(deb_index, end_index - deb_index);
deb_index = connection_string.find(delimiter, end_index + std::size_t(1));
if (deb_index == std::string::npos)
GUM_ERROR(DatabaseError, "could not determine the database login");
GUM_ERROR(DatabaseError,
"could not determine the database login from string " <<
connection_string);
deb_index += std::size_t(1);
end_index = connection_string.find(delimiter, deb_index);
if (end_index == std::string::npos)
GUM_ERROR(DatabaseError, "could not determine the database login");
GUM_ERROR(DatabaseError,
"could not determine the database login from string " <<
connection_string);
std::string login =
connection_string.substr(deb_index, end_index - deb_index);
deb_index = connection_string.find(delimiter, end_index + std::size_t(1));
if (deb_index == std::string::npos)
GUM_ERROR(DatabaseError, "could not determine the database password");
GUM_ERROR(DatabaseError,
"could not determine the database password from string " <<
connection_string);
deb_index += std::size_t(1);
end_index = connection_string.find(delimiter, deb_index);
if (end_index == std::string::npos)
GUM_ERROR(DatabaseError, "could not determine the database password");
GUM_ERROR(DatabaseError,
"could not determine the database password from string " <<
connection_string);
std::string password =
connection_string.substr(deb_index, end_index - deb_index);
......
......@@ -373,7 +373,8 @@ namespace gum {
if (this->isMissingSymbol(str)) {
return DBTranslatedValue{std::numeric_limits< float >::max()};
} else
GUM_ERROR(TypeError, "the string is not a number");
GUM_ERROR(TypeError, "String \"" << str <<
"\" cannot be translated because it is not a number");
}
// here we know that the string is a number
......@@ -393,7 +394,7 @@ namespace gum {
// check if we are allowed to update the domain of the variable
if (!__fit_range) {
GUM_ERROR(UnknownLabelInDatabase,
"the string cannot be translated because it is "
"String \"" << str << "\" cannot be translated because it is "
"out of the domain of the continuous variable");
}
......@@ -424,8 +425,9 @@ namespace gum {
const float miss_val = std::stof(missing.first);
if ((miss_val >= number) && (miss_val <= upper_bound)) {
GUM_ERROR(OperationNotAllowed,
"the string would induce a new domain containing "
"an already translated missing symbol");
"String \"" << str << "\" cannot be translated because " <<
"it would induce a new domain containing an already " <<
"translated missing symbol");
}
}
}
......@@ -456,8 +458,9 @@ namespace gum {
const float miss_val = std::stof(missing.first);
if ((miss_val >= lower_bound) && (miss_val <= number)) {
GUM_ERROR(OperationNotAllowed,
"the string would induce a new domain containing "
"an already translated missing symbol");
"String \"" << str << "\" cannot be translated because " <<
"it would induce a new domain containing an already " <<
"translated missing symbol");
}
}
}
......@@ -497,8 +500,9 @@ namespace gum {
if ((translated_val.cont_val < __variable.lowerBound())
|| (translated_val.cont_val > __variable.upperBound())) {
GUM_ERROR(UnknownLabelInDatabase,
"The back translation could not be found because the "
"value is outside the domain of the continuous variable");
"The back translation of " << translated_val.cont_val <<
" could not be found because the value is outside the " <<
"domain of the continuous variable");
}
char buffer[100];
......
......@@ -381,10 +381,11 @@ namespace gum {
return DBTranslatedValue{this->_back_dico.first(str)};
} catch (gum::Exception&) {
if (!DBCell::isReal(str)) {
GUM_ERROR(TypeError, "the string is not a number");
GUM_ERROR(TypeError, "String \"" << str <<
"\" cannot be translated because it is not a number");
} else {
GUM_ERROR(UnknownLabelInDatabase,
"The translation could not be found");
"The translation of \"" << str << "\" could not be found");
}
}
}
......@@ -404,7 +405,8 @@ namespace gum {
return *(this->_missing_symbols.begin());
else
GUM_ERROR(UnknownLabelInDatabase,
"The back translation could not be found");
"The back translation of \"" << translated_val.discr_val <<
"\" could not be found");
}
}
......
......@@ -259,12 +259,15 @@ namespace gum {
if (this->hasEditableDictionary()) {
const std::size_t size = __variable.domainSize();
if (size >= this->_max_dico_entries)
GUM_ERROR(SizeError, "the dictionary is full");
GUM_ERROR(SizeError,
"String \"" << str << "\" cannot be translated " <<
"because the dictionary is already full" );
__variable.addLabel(str);
this->_back_dico.insert(size, str);
return DBTranslatedValue{size};
} else
GUM_ERROR(UnknownLabelInDatabase, "The translation could not be found");
GUM_ERROR(UnknownLabelInDatabase,
"The translation of \"" << str << "\" could not be found");
}
}
......@@ -282,7 +285,8 @@ namespace gum {
return *(this->_missing_symbols.begin());
else
GUM_ERROR(UnknownLabelInDatabase,
"The back translation could not be found");
"The back translation of \"" << translated_val.discr_val <<
"\" could not be found");
}
}
......
......@@ -322,12 +322,16 @@ namespace gum {
// check if we are allowed to update the range variable
if (!this->hasEditableDictionary()) {
GUM_ERROR(UnknownLabelInDatabase, "The translation could not be found");
GUM_ERROR(UnknownLabelInDatabase,
"The translation of String \"" << str <<
"\" could not be found");
}
// check if str could correspond to a bound of the range variable
if (!DBCell::isInteger(str)) {
GUM_ERROR(TypeError, "The string cannot be converted into an integer");
GUM_ERROR(TypeError,
"String \"" << str << "\" cannot be translated because " <<
"it cannot be converted into an integer");
}
const long new_value = std::stol(str);
......@@ -335,8 +339,8 @@ namespace gum {
// translated, raise an exception
if (__translated_int_missing_symbols.exists(new_value)) {
GUM_ERROR(OperationNotAllowed,
"the string corresponds to an "
"already translated missing symbol");
"String \"" << str << "\" cannot be translated because " <<
"it corresponds to an already translated missing symbol");
}
// now, we can try to add str as a new bound of the range variable
......@@ -348,7 +352,9 @@ namespace gum {
// in the above test.
if (__variable.minVal() > __variable.maxVal()) {
if (this->_max_dico_entries == 0) {
GUM_ERROR(SizeError, "the dictionary is full");
GUM_ERROR(SizeError,
"String \"" << str << "\" cannot be translated because " <<
"the dictionary is already full");
}
__variable.setMinVal(new_value);
__variable.setMaxVal(new_value);
......@@ -367,14 +373,17 @@ namespace gum {
if (new_value < __variable.minVal()) {
if (std::size_t(upper_bound - new_value + 1) > this->_max_dico_entries)
GUM_ERROR(SizeError, "the dictionary is full");
GUM_ERROR(SizeError,
"String \"" << str << "\" cannot be translated because " <<
"the dictionary is already full");
// check that there does not already exist a translated missing
// value within the new bounds of the range variable
for (const auto& missing : __translated_int_missing_symbols) {
if ((missing >= new_value) && (missing <= upper_bound)) {
GUM_ERROR(OperationNotAllowed,
"the string would induce a new range containing "
"String \"" << str << "\" cannot be translated " <<
"because it would induce a new range containing " <<
"an already translated missing symbol");
}
}
......@@ -404,14 +413,17 @@ namespace gum {
return DBTranslatedValue{index};
} else {
if (std::size_t(new_value - lower_bound + 1) > this->_max_dico_entries)
GUM_ERROR(SizeError, "the dictionary is full");
GUM_ERROR(SizeError,
"String \"" << str << "\" cannot be translated because " <<
"the dictionary is already full");
// check that there does not already exist a translated missing
// value within the new bounds of the range variable
for (const auto& missing : __translated_int_missing_symbols) {
if ((missing <= new_value) && (missing >= lower_bound)) {
GUM_ERROR(OperationNotAllowed,
"the string would induce a new range containing "
"String \"" << str << "\" cannot be translated " <<
"because it would induce a new range containing " <<
"an already translated missing symbol");
}
}
......@@ -459,7 +471,8 @@ namespace gum {
}
GUM_ERROR(UnknownLabelInDatabase,
"The back translation could not be found");
"The back translation of \"" << translated_val.discr_val <<
"\" could not be found");
}
}
......
......@@ -379,7 +379,8 @@ namespace gum {
const std::vector< std::string, OTHER_ALLOC< std::string > >& row,
const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the translator could not be found");
GUM_ERROR(UndefinedElement,
"Translator #" << k << " could not be found");
return __translators[k]->translate(row[__columns[k]]);
}
......@@ -397,7 +398,8 @@ namespace gum {
INLINE std::string DBTranslatorSet< ALLOC >::translateBackSafe(
const DBTranslatedValue translated_val, const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the translator could not be found");
GUM_ERROR(UndefinedElement,
"Translator #" << k << "could not be found");
return __translators[k]->translateBack(translated_val);
}
......@@ -417,7 +419,8 @@ namespace gum {
INLINE bool DBTranslatorSet< ALLOC >::isMissingValueSafe(
const DBTranslatedValue translated_val, const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the translator could not be found");
GUM_ERROR(UndefinedElement,
"Translator #" << k << "could not be found");
return __translators[k]->isMissingValue(translated_val);
}
......@@ -443,7 +446,8 @@ namespace gum {
INLINE DBTranslator< ALLOC >&
DBTranslatorSet< ALLOC >::translatorSafe(const std::size_t k) {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the translator could not be found");
GUM_ERROR(UndefinedElement,
"Translator #" << k << "could not be found");
return *(__translators[k]);
}
......@@ -453,7 +457,8 @@ namespace gum {
INLINE const DBTranslator< ALLOC >&
DBTranslatorSet< ALLOC >::translatorSafe(const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the translator could not be found");
GUM_ERROR(UndefinedElement,
"Translator #" << k << "could not be found");
return *(__translators[k]);
}
......@@ -471,7 +476,7 @@ namespace gum {
INLINE std::size_t
DBTranslatorSet< ALLOC >::domainSizeSafe(const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the variable could not be found");
GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
return __translators[k]->domainSize();
}
......@@ -489,7 +494,7 @@ namespace gum {
INLINE const Variable&
DBTranslatorSet< ALLOC >::variableSafe(const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the variable could not be found");
GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
return *(__translators[k]->variable());
}
......@@ -509,7 +514,7 @@ namespace gum {
INLINE bool
DBTranslatorSet< ALLOC >::needsReorderingSafe(const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the variable could not be found");
GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
return __translators[k]->needsReordering();
}
......@@ -533,7 +538,7 @@ namespace gum {
ALLOC< std::pair< std::size_t, std::size_t > > >
DBTranslatorSet< ALLOC >::reorderSafe(const std::size_t k) {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the variable could not be found");
GUM_ERROR(UndefinedElement, "Variable #" << k << "could not be found");
return __translators[k]->reorder();
}
......@@ -553,7 +558,7 @@ namespace gum {
INLINE std::size_t
DBTranslatorSet< ALLOC >::inputColumnSafe(const std::size_t k) const {
if (__translators.size() <= k)
GUM_ERROR(UndefinedElement, "the column could not be found");
GUM_ERROR(UndefinedElement, "Column #" << k << "could not be found");
return __columns[k];
}
......
......@@ -144,7 +144,7 @@ namespace gum {
default:
GUM_ERROR(NotImplementedYet,
"fillDatabase has not been implemented yet for this "
"type of IDBInitializeInputType");
"type of IDBInitializerInputType");
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment