Catch exception thrown when loading config files.

Thrown exception has been changed to be std::runtime_error, includes regression test (program does not crash when loading unknown keys).
Sends error/diagnostic message to std::cerr.

Addresses #3430
This commit is contained in:
Joseph Lenox 2016-07-19 00:31:10 -05:00
parent 848374602d
commit 6736ff5fa6
3 changed files with 34 additions and 4 deletions

View File

@ -4,6 +4,7 @@
#include <ctime>
#include <fstream>
#include <iostream>
#include <exception> // std::runtime_error
#include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
@ -124,7 +125,7 @@ ConfigBase::serialize(const t_config_option_key &opt_key) const {
bool
ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str, bool append) {
const ConfigOptionDef* optdef = this->def->get(opt_key);
if (optdef == NULL) throw "Calling set_deserialize() on unknown option";
if (optdef == NULL) throw std::runtime_error("Calling set_deserialize() on unknown option");
if (!optdef->shortcut.empty()) {
for (std::vector<t_config_option_key>::const_iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it) {
if (!this->set_deserialize(*it, str)) return false;
@ -202,7 +203,12 @@ ConfigBase::load(const std::string &file)
pt::ptree tree;
pt::read_ini(file, tree);
BOOST_FOREACH(const pt::ptree::value_type &v, tree) {
this->set_deserialize(v.first.c_str(), v.second.get_value<std::string>().c_str());
try {
this->set_deserialize(v.first.c_str(), v.second.get_value<std::string>().c_str());
} catch (std::runtime_error& e) {
// skip over errors in the config file but print a warning.
std::cerr << "Caught exception at option " << v.first.c_str() << ".\n";
}
}
}
@ -212,7 +218,7 @@ ConfigBase::save(const std::string &file) const
using namespace std;
ofstream c;
c.open(file.c_str(), ios::out | ios::trunc);
{
time_t now;
time(&now);
@ -220,7 +226,7 @@ ConfigBase::save(const std::string &file) const
strftime(buf, sizeof buf, "%F %T", gmtime(&now));
c << "# generated by Slic3r " << SLIC3R_VERSION << " on " << buf << endl;
}
t_config_option_keys my_keys = this->keys();
for (t_config_option_keys::const_iterator opt_key = my_keys.begin(); opt_key != my_keys.end(); ++opt_key)
c << *opt_key << " = " << this->serialize(*opt_key) << endl;

17
xs/t/22_config.t Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/perl
use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 1;
{
use Cwd qw(abs_path);
use File::Basename qw(dirname);
my $class = Slic3r::Config->new;
my $path = abs_path($0);
my $config = $class->_load(dirname($path)."/inc/22_config_bad_config_options.ini");
ok 1, 'did not crash on reading invalid items in config';
}
__END__

View File

@ -0,0 +1,7 @@
# generated by Slic3r 1.1.7 on Tue Aug 19 21:49:50 2014
avoid_crossing_perimeters = 1
bed_size = 200,180
g0 = 0
perimeter_acceleration = 0
support_material_extruder = 1
support_material_extrusion_width = 0