summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mbgl/map/map.cpp9
-rw-r--r--src/mbgl/style/observer.hpp1
-rw-r--r--src/mbgl/style/parser.cpp15
-rw-r--r--src/mbgl/style/parser.hpp5
-rw-r--r--src/mbgl/style/style.cpp10
-rw-r--r--test/fixtures/style_parser/non-object.info.json4
-rw-r--r--test/map/map.cpp2
-rw-r--r--test/style/style_parser.cpp7
8 files changed, 41 insertions, 12 deletions
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 2e7dc06e8b..3a307735ab 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -38,6 +38,7 @@ public:
Impl(View&, FileSource&, MapMode, GLContextMode, ConstrainMode, ViewportMode);
void onNeedsRepaint() override;
+ void onStyleError() override;
void onResourceError(std::exception_ptr) override;
void update();
@@ -316,6 +317,8 @@ void Map::setStyleURL(const std::string& url) {
} else {
Log::Error(Event::Setup, "loading style failed: %s", res.error->message.c_str());
}
+ impl->onStyleError();
+ impl->onResourceError(std::make_exception_ptr(std::runtime_error(res.error->message)));
} else if (res.notModified || res.noContent) {
return;
} else {
@@ -343,8 +346,8 @@ void Map::setStyleJSON(const std::string& json) {
}
void Map::Impl::loadStyleJSON(const std::string& json) {
- style->setJSON(json);
style->setObserver(this);
+ style->setJSON(json);
styleJSON = json;
// force style cascade, causing all pending transitions to complete.
@@ -908,6 +911,10 @@ void Map::Impl::onNeedsRepaint() {
asyncUpdate.send();
}
+void Map::Impl::onStyleError() {
+ view.notifyMapChange(MapChangeDidFailLoadingMap);
+}
+
void Map::Impl::onResourceError(std::exception_ptr error) {
if (mode == MapMode::Still && callback) {
callback(error, {});
diff --git a/src/mbgl/style/observer.hpp b/src/mbgl/style/observer.hpp
index 2c48114669..c4d31ae249 100644
--- a/src/mbgl/style/observer.hpp
+++ b/src/mbgl/style/observer.hpp
@@ -18,6 +18,7 @@ public:
* and `onNeedsRepaint` will be called.
*/
void onNeedsRepaint() override {}
+ virtual void onStyleError() {}
virtual void onResourceError(std::exception_ptr) {}
};
diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp
index bc05b5484a..e53fac2667 100644
--- a/src/mbgl/style/parser.cpp
+++ b/src/mbgl/style/parser.cpp
@@ -14,24 +14,27 @@
#include <algorithm>
#include <set>
+#include <sstream>
namespace mbgl {
namespace style {
Parser::~Parser() = default;
-void Parser::parse(const std::string& json) {
+StyleParseResult Parser::parse(const std::string& json) {
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> document;
document.Parse<0>(json.c_str());
if (document.HasParseError()) {
- Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError()));
- return;
+ std::stringstream message;
+ message << document.GetErrorOffset() << " - "
+ << rapidjson::GetParseError_En(document.GetParseError());
+
+ return std::make_exception_ptr(std::runtime_error(message.str()));
}
if (!document.IsObject()) {
- Log::Error(Event::ParseStyle, "Style JSON must be an object");
- return;
+ return std::make_exception_ptr(std::runtime_error("style must be an object"));
}
if (document.HasMember("version")) {
@@ -100,6 +103,8 @@ void Parser::parse(const std::string& json) {
glyphURL = { glyphs.GetString(), glyphs.GetStringLength() };
}
}
+
+ return nullptr;
}
void Parser::parseSources(const JSValue& value) {
diff --git a/src/mbgl/style/parser.hpp b/src/mbgl/style/parser.hpp
index a6a71ed817..a05a0b316a 100644
--- a/src/mbgl/style/parser.hpp
+++ b/src/mbgl/style/parser.hpp
@@ -9,6 +9,7 @@
#include <vector>
#include <memory>
+#include <stdexcept>
#include <string>
#include <unordered_map>
#include <forward_list>
@@ -16,11 +17,13 @@
namespace mbgl {
namespace style {
+using StyleParseResult = std::exception_ptr;
+
class Parser {
public:
~Parser();
- void parse(const std::string&);
+ StyleParseResult parse(const std::string&);
std::string spriteURL;
std::string glyphURL;
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 1cf64002fb..e04384a96e 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -90,7 +90,15 @@ void Style::setJSON(const std::string& json) {
classes.clear();
Parser parser;
- parser.parse(json);
+ auto error = parser.parse(json);
+
+ if (error) {
+ Log::Error(Event::ParseStyle, "Failed to parse style: %s", util::toString(error).c_str());
+ observer->onStyleError();
+ observer->onResourceError(error);
+
+ return;
+ }
for (auto& source : parser.sources) {
addSource(std::move(source));
diff --git a/test/fixtures/style_parser/non-object.info.json b/test/fixtures/style_parser/non-object.info.json
index d1b67e2ea6..ac6ea00d97 100644
--- a/test/fixtures/style_parser/non-object.info.json
+++ b/test/fixtures/style_parser/non-object.info.json
@@ -1,7 +1,7 @@
{
"default": {
"log": [
- [1, "ERROR", "ParseStyle", "Style JSON must be an object"]
+ [1, "ERROR", "ParseStyle", "Failed to parse style: style must be an object"]
]
}
-} \ No newline at end of file
+}
diff --git a/test/map/map.cpp b/test/map/map.cpp
index 2dc8aad927..7e0bbd0234 100644
--- a/test/map/map.cpp
+++ b/test/map/map.cpp
@@ -68,7 +68,7 @@ TEST(Map, SetStyleInvalidJSON) {
auto observer = Log::removeObserver();
auto flo = dynamic_cast<FixtureLogObserver*>(observer.get());
EXPECT_EQ(1u, flo->count({ EventSeverity::Error, Event::ParseStyle, -1,
- "Error parsing style JSON at 0: Invalid value." }));
+ "Failed to parse style: 0 - Invalid value." }));
auto unchecked = flo->unchecked();
EXPECT_TRUE(unchecked.empty()) << unchecked;
}
diff --git a/test/style/style_parser.cpp b/test/style/style_parser.cpp
index b7806c11cc..3e1149c997 100644
--- a/test/style/style_parser.cpp
+++ b/test/style/style_parser.cpp
@@ -4,6 +4,7 @@
#include <mbgl/style/parser.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/enum.hpp>
+#include <mbgl/util/string.hpp>
#include <mbgl/util/tileset.hpp>
#include <rapidjson/document.h>
@@ -32,7 +33,11 @@ TEST_P(StyleParserTest, ParseStyle) {
Log::setObserver(std::unique_ptr<Log::Observer>(observer));
style::Parser parser;
- parser.parse(util::read_file(base + ".style.json"));
+ auto error = parser.parse(util::read_file(base + ".style.json"));
+
+ if (error) {
+ Log::Error(Event::ParseStyle, "Failed to parse style: %s", util::toString(error).c_str());
+ }
for (auto it = infoDoc.MemberBegin(), end = infoDoc.MemberEnd(); it != end; it++) {
const std::string name { it->name.GetString(), it->name.GetStringLength() };