Core/Config: User-friendlyfy configuration parsing errors

It will now print useful error messages that pinpoint the issue
with the config file (missing file, bad syntax, etc)

In memory of MitchesD that lost 18 hours finding a problem with
his config because of a duplicated line.
This commit is contained in:
DDuarte
2014-07-29 01:47:00 +01:00
parent 833195062c
commit 0e52b111f3
5 changed files with 23 additions and 15 deletions

View File

@@ -68,10 +68,10 @@ int main(int argc, char** argv)
if (vm.count("help"))
return 0;
if (!sConfigMgr->LoadInitial(configFile))
std::string configError;
if (!sConfigMgr->LoadInitial(configFile, configError))
{
printf("Invalid or missing configuration file : %s\n", configFile.c_str());
printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n");
printf("Error in config file: %s\n", configError.c_str());
return 1;
}

View File

@@ -408,9 +408,10 @@ void World::LoadConfigSettings(bool reload)
{
if (reload)
{
if (!sConfigMgr->Reload())
std::string configError;
if (!sConfigMgr->Reload(configError))
{
TC_LOG_ERROR("misc", "World settings reload fail: can't read settings from %s.", sConfigMgr->GetFilename().c_str());
TC_LOG_ERROR("misc", "World settings reload fail: %s.", configError.c_str());
return;
}
sLog->LoadFromConfig();

View File

@@ -25,7 +25,7 @@
using namespace boost::property_tree;
bool ConfigMgr::LoadInitial(std::string const& file)
bool ConfigMgr::LoadInitial(std::string const& file, std::string& error)
{
std::lock_guard<std::mutex> lock(_configLock);
@@ -34,25 +34,32 @@ bool ConfigMgr::LoadInitial(std::string const& file)
try
{
ptree fullTree;
boost::property_tree::ini_parser::read_ini(file, fullTree);
ini_parser::read_ini(file, fullTree);
if (fullTree.empty())
{
error = "empty file (" + file + ")";
return false;
}
// Since we're using only one section per config file, we skip the section and have direct property access
_config = fullTree.begin()->second;
}
catch (std::exception const& /*ex*/)
catch (ini_parser::ini_parser_error const& e)
{
if (e.line() == 0)
error = e.message() + " (" + e.filename() + ")";
else
error = e.message() + " (" + e.filename() + ":" + std::to_string(e.line()) + ")";
return false;
}
return true;
}
bool ConfigMgr::Reload()
bool ConfigMgr::Reload(std::string& error)
{
return LoadInitial(_filename.c_str());
return LoadInitial(_filename.c_str(), error);
}
std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def)

View File

@@ -31,7 +31,7 @@ class ConfigMgr
public:
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
bool LoadInitial(std::string const& file);
bool LoadInitial(std::string const& file, std::string& error);
static ConfigMgr* instance()
{
@@ -39,7 +39,7 @@ public:
return &instance;
}
bool Reload();
bool Reload(std::string& error);
std::string GetStringDefault(std::string const& name, const std::string& def);
bool GetBoolDefault(std::string const& name, bool def);

View File

@@ -109,10 +109,10 @@ extern int main(int argc, char** argv)
WinServiceRun();
#endif
if (!sConfigMgr->LoadInitial(configFile))
std::string configError;
if (!sConfigMgr->LoadInitial(configFile, configError))
{
printf("Invalid or missing configuration file : %s\n", configFile.c_str());
printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!\n");
printf("Error in config file: %s\n", configError.c_str());
return 1;
}