Skip to content

Commit

Permalink
Improve error messages.
Browse files Browse the repository at this point in the history
  • Loading branch information
herm committed Mar 8, 2012
1 parent 8b0b9ed commit cd8cfc6
Show file tree
Hide file tree
Showing 18 changed files with 115 additions and 44 deletions.
20 changes: 8 additions & 12 deletions include/mapnik/config_error.hpp
Expand Up @@ -28,29 +28,25 @@

namespace mapnik {

class xml_node;
class config_error : public std::exception
{
public:
config_error() {}

config_error( const std::string & what ) :
what_( what )
{
}
config_error(std::string const& what, xml_node const* node = 0, std::string const& filename="");
config_error(unsigned line_number, std::string const& filename, std::string const& what);
virtual ~config_error() throw() {}

virtual const char * what() const throw()
{
return what_.c_str();
}
virtual const char * what() const throw();

void append_context(const std::string & ctx) const
{
what_ += " " + ctx;
}
void append_context(const std::string & ctx, xml_node const* node = 0, std::string const& filename="") const;

protected:
mutable std::string what_;
mutable unsigned line_number_;
mutable std::string file_;
mutable std::string node_name_;
};
}

Expand Down
1 change: 0 additions & 1 deletion include/mapnik/raster_colorizer.hpp
Expand Up @@ -39,7 +39,6 @@

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/color.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/enumeration.hpp>
Expand Down
1 change: 0 additions & 1 deletion include/mapnik/value.hpp
Expand Up @@ -26,7 +26,6 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>

// boost
#include <boost/variant.hpp>
Expand Down
3 changes: 3 additions & 0 deletions include/mapnik/xml_tree.hpp
Expand Up @@ -96,8 +96,11 @@ class xml_node
void add_attribute(std::string const& name, std::string const& value);
attribute_map const& get_attributes() const;

bool processed() const;
void set_processed(bool processed) const;

unsigned line() const;

const_iterator begin() const;
const_iterator end() const;

Expand Down
1 change: 0 additions & 1 deletion src/agg/agg_renderer.cpp
Expand Up @@ -26,7 +26,6 @@
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/map.hpp>
Expand Down
1 change: 1 addition & 0 deletions src/build.py
Expand Up @@ -179,6 +179,7 @@ def ldconfig(*args,**kwargs):
text_placements/simple.cpp
text_properties.cpp
xml_tree.cpp
config_error.cpp
"""
)

Expand Down
1 change: 0 additions & 1 deletion src/cairo_renderer.cpp
Expand Up @@ -29,7 +29,6 @@
#include <mapnik/unicode.hpp>
#include <mapnik/markers_placement.hpp>
#include <mapnik/arrow.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
Expand Down
44 changes: 44 additions & 0 deletions src/config_error.cpp
@@ -0,0 +1,44 @@
#include <mapnik/config_error.hpp>
#include <mapnik/xml_tree.hpp>

namespace mapnik
{
config_error::config_error(std::string const& what, xml_node const* node, std::string const& filename)
: what_( what ), file_(filename)
{
if (node)
{
node_name_ = node->name();
line_number_ = node->line();
}
}


config_error::config_error(unsigned line_number, std::string const& filename, std::string const& what)
: what_( what ), line_number_(line_number), file_(filename)
{

}

char const* config_error::what() const throw()
{
std::stringstream s;
s << file_;
if (line_number_ > 0) s << " line " << line_number_;
if (!node_name_.empty()) s << " in node "<< node_name_;
if (line_number_ > 0 || !file_.empty()) s << ": ";
s << what_;
return s.str().c_str();
}

void config_error::append_context(const std::string & ctx, xml_node const* node, std::string const& filename) const
{
what_ += " " + ctx;
if (node)
{
if (!line_number_) line_number_ = node->line();
if (node_name_.empty()) node_name_ = node->name();
if (file_.empty()) file_ = filename;
}
}
}
3 changes: 2 additions & 1 deletion src/formatting/registry.cpp
Expand Up @@ -25,6 +25,7 @@
#include <mapnik/formatting/format.hpp>
#include <mapnik/formatting/expression.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/config_error.hpp>

namespace mapnik
{
Expand All @@ -50,7 +51,7 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o
node_ptr registry::from_xml(xml_node const& xml)
{
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(xml.name());
if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'");
if (itr == map_.end()) throw config_error("Unknown element '" + xml.name() + "'", &xml);
return itr->second(xml);
}
} //ns formatting
Expand Down
1 change: 0 additions & 1 deletion src/grid/grid_renderer.cpp
Expand Up @@ -31,7 +31,6 @@

#include <mapnik/marker_cache.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/font_set.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/map.hpp>
Expand Down
15 changes: 3 additions & 12 deletions src/libxml2_loader.cpp
Expand Up @@ -77,8 +77,7 @@ class libxml2_loader : boost::noncopyable
boost::filesystem::path path(filename);
if (!boost::filesystem::exists(path))
{
throw config_error(string("Could not load map file '") +
filename + "': File does not exist");
throw config_error(string("Could not load map file: File does not exist"), 0, filename);
}

xmlDocPtr doc = xmlCtxtReadFile(ctx_, filename.c_str(), encoding_, options_);
Expand All @@ -93,15 +92,7 @@ class libxml2_loader : boost::noncopyable
os << ": " << std::endl << error->message;
// remove CR
std::string msg = os.str().substr(0, os.str().size() - 1);
config_error ex(msg);

os.str("");
os << "(encountered in file '" << error->file << "' at line "
<< error->line << ")";

ex.append_context(os.str());

throw ex;
throw config_error(error->line, error->file, msg);
}
}

Expand Down Expand Up @@ -148,7 +139,7 @@ class libxml2_loader : boost::noncopyable
{
os << ": " << std::endl << error->message;
}
throw config_error(os.str());
throw config_error(error->line, error->file, os.str());
}

int iXIncludeReturn = xmlXIncludeProcessFlags(doc, options_);
Expand Down
14 changes: 7 additions & 7 deletions src/load_map.cpp
Expand Up @@ -195,7 +195,7 @@ expression_ptr map_parser::parse_expr(std::string const& str)
expression_ptr expr(boost::make_shared<expr_node>(true));
if (!expression_factory::parse_from_string(expr,str,expr_grammar_))
{
throw mapnik::config_error( "Failed to parse expression: '" + str + "'" );
throw mapnik::config_error( "Failed to parse expression '" + str + "'" );
}
return expr;

Expand Down Expand Up @@ -354,7 +354,7 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
}
catch (const config_error & ex)
{
ex.append_context("(in node Map)");
ex.append_context("", &map_node, filename_);
throw;
}

Expand Down Expand Up @@ -458,7 +458,7 @@ void map_parser::parse_map_include(Map & map, xml_node const& include)
}
}
} catch (const config_error & ex) {
ex.append_context(std::string("in map '") + filename_ + "'");
ex.append_context("", &include, filename_);
throw;
}

Expand Down Expand Up @@ -489,7 +489,7 @@ void map_parser::parse_style(Map & map, xml_node const& sty)

map.insert_style(name, style);
} catch (const config_error & ex) {
ex.append_context(std::string("in style '") + name + "'");
ex.append_context(std::string("in style '") + name + "'", &sty, filename_);
throw;
}
}
Expand All @@ -504,7 +504,7 @@ void map_parser::parse_metawriter(Map & map, xml_node const& pt)
writer = metawriter_create(pt);
map.insert_metawriter(name, writer);
} catch (const config_error & ex) {
ex.append_context(std::string("in meta writer '") + name + "'");
ex.append_context(std::string("in meta writer '") + name + "'", &pt, filename_);
}
}

Expand Down Expand Up @@ -533,7 +533,7 @@ void map_parser::parse_fontset(Map & map, xml_node const& fset)
// when it's parsed
fontsets_.insert(pair<std::string, font_set>(name, fontset));
} catch (const config_error & ex) {
ex.append_context(std::string("in FontSet '") + name + "'");
ex.append_context(std::string("in FontSet '") + name + "'", &fset, filename_);
throw;
}
}
Expand All @@ -551,7 +551,7 @@ void map_parser::parse_font(font_set &fset, xml_node const& f)
}
else
{
throw config_error(std::string("Must have 'face-name' set"));
throw config_error("Must have 'face-name' set", &f, filename_);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/metawriter_factory.cpp
Expand Up @@ -26,6 +26,7 @@
#include <mapnik/metawriter_inmem.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/config_error.hpp>

#include <boost/optional.hpp>

Expand Down Expand Up @@ -60,7 +61,7 @@ metawriter_create(xml_node const& pt)
metawriter_inmem_ptr inmem = metawriter_inmem_ptr(new metawriter_inmem(properties));
writer = inmem;
} else {
throw config_error(string("Unknown type '") + type + "'");
throw config_error(string("Unknown type '") + type + "'", &pt);
}

return writer;
Expand Down
26 changes: 25 additions & 1 deletion src/processed_text.cpp
@@ -1,4 +1,28 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/

#include <mapnik/processed_text.hpp>
#include <mapnik/config_error.hpp>

namespace mapnik
{

Expand Down Expand Up @@ -43,7 +67,7 @@ string_info &processed_text::get_string_info()
{
if (!p.fontset.get_name().empty())
{
throw config_error("Unable to find specified font set '" + p.face_name + "'");
throw config_error("Unable to find specified font set '" + p.fontset.get_name() + "'");
} else if (!p.face_name.empty()) {
throw config_error("Unable to find specified font face '" + p.face_name + "'");
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/text_placements/registry.cpp
Expand Up @@ -23,6 +23,7 @@
#include <mapnik/text_placements/registry.hpp>
#include <mapnik/text_placements/simple.hpp>
#include <mapnik/text_placements/list.hpp>
#include <mapnik/config_error.hpp>

namespace mapnik
{
Expand All @@ -47,7 +48,7 @@ void registry::register_name(std::string name, from_xml_function_ptr ptr, bool o
text_placements_ptr registry::from_xml(std::string name, xml_node const& xml, fontset_map const& fontsets)
{
std::map<std::string, from_xml_function_ptr>::const_iterator itr = map_.find(name);
if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'");
if (itr == map_.end()) throw config_error("Unknown placement-type '" + name + "'", &xml);
return itr->second(xml, fontsets);
}
} //ns formatting
Expand Down
7 changes: 4 additions & 3 deletions src/text_properties.cpp
Expand Up @@ -26,6 +26,7 @@
#include <mapnik/expression_string.hpp>
#include <mapnik/formatting/text.hpp>
#include <mapnik/xml_tree.hpp>
#include <mapnik/config_error.hpp>

namespace mapnik
{
Expand Down Expand Up @@ -266,16 +267,16 @@ void char_properties::from_xml(xml_node const& sym, fontset_map const& fontsets)
fontset = itr->second;
} else
{
throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'");
throw config_error("Unable to find any fontset named '" + *fontset_name_ + "'", &sym);
}
}
if (!face_name.empty() && !fontset.get_name().empty())
{
throw config_error(std::string("Can't have both face-name and fontset-name"));
throw config_error("Can't have both face-name and fontset-name", &sym);
}
if (face_name.empty() && fontset.get_name().empty())
{
throw config_error(std::string("Must have face-name or fontset-name"));
throw config_error("Must have face-name or fontset-name", &sym);
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/xml_tree.cpp
Expand Up @@ -288,6 +288,11 @@ void xml_node::set_processed(bool processed) const
processed_ = processed;
}

bool xml_node::processed() const
{
return processed_;
}

xml_node::const_iterator xml_node::begin() const
{
return children_.begin();
Expand Down Expand Up @@ -399,6 +404,11 @@ T xml_node::get_value() const
return *result;
}

unsigned xml_node::line() const
{
return line_;
}

#define compile_get_opt_attr(T) template boost::optional<T> xml_node::get_opt_attr<T>(std::string const&) const
#define compile_get_attr(T) template T xml_node::get_attr<T>(std::string const&) const; template T xml_node::get_attr<T>(std::string const&, T const&) const
#define compile_get_value(T) template T xml_node::get_value<T>() const
Expand Down

0 comments on commit cd8cfc6

Please sign in to comment.