summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2018-07-16 14:20:09 +0200
committerJohn Firebaugh <john.firebaugh@gmail.com>2018-08-27 14:07:40 -0700
commit30272924a907b4d557e45932bf3cc3d392d5e85b (patch)
tree83ac18d933f0c1d87f43ba5975a2c981eda34b98
parent1e454642c8bc99698d25105fe0034916e2930fe6 (diff)
downloadqtlocation-mapboxgl-30272924a907b4d557e45932bf3cc3d392d5e85b.tar.gz
[node] capture invalid input data as `ParseError` objects
This allows us to distinguish them from other types of errors
-rw-r--r--platform/node/src/node_map.cpp37
-rw-r--r--platform/node/src/node_map.hpp3
-rw-r--r--platform/node/test/js/map.test.js8
-rw-r--r--src/mbgl/style/sources/raster_source.cpp3
-rw-r--r--src/mbgl/style/sources/vector_source.cpp3
5 files changed, 47 insertions, 7 deletions
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp
index 0cc93d7e95..7dbccfcf41 100644
--- a/platform/node/src/node_map.cpp
+++ b/platform/node/src/node_map.cpp
@@ -47,6 +47,7 @@ struct NodeMap::RenderOptions {
};
Nan::Persistent<v8::Function> NodeMap::constructor;
+Nan::Persistent<v8::Object> NodeMap::parseError;
static const char* releasedMessage() {
return "Map resources have already been released";
@@ -57,6 +58,20 @@ void NodeMapObserver::onDidFailLoadingMap(std::exception_ptr error) {
}
void NodeMap::Init(v8::Local<v8::Object> target) {
+ // Define a custom error class for parse errors
+ auto script = Nan::New<v8::UnboundScript>(Nan::New(R"JS(
+class ParseError extends Error {
+ constructor(...params) {
+ super(...params);
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, ParseError);
+ }
+ }
+}
+ParseError)JS").ToLocalChecked()).ToLocalChecked();
+ parseError.Reset(Nan::To<v8::Object>(Nan::RunScript(script).ToLocalChecked()).ToLocalChecked());
+ Nan::Set(target, Nan::New("ParseError").ToLocalChecked(), Nan::New(parseError));
+
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Map").ToLocalChecked());
@@ -216,6 +231,8 @@ void NodeMap::Load(const Nan::FunctionCallbackInfo<v8::Value>& info) {
try {
nodeMap->map->getStyle().loadJSON(style);
+ } catch (const mbgl::util::StyleParseException& ex) {
+ return Nan::ThrowError(ParseError(ex.what()));
} catch (const std::exception &ex) {
return Nan::ThrowError(ex.what());
}
@@ -408,9 +425,11 @@ void NodeMap::Render(const Nan::FunctionCallbackInfo<v8::Value>& info) {
nodeMap->req = std::make_unique<RenderRequest>(Nan::To<v8::Function>(info[1]).ToLocalChecked());
nodeMap->startRender(std::move(options));
- } catch (mbgl::style::conversion::Error& err) {
+ } catch (const mbgl::style::conversion::Error& err) {
return Nan::ThrowTypeError(err.message.c_str());
- } catch (mbgl::util::Exception &ex) {
+ } catch (const mbgl::util::StyleParseException& ex) {
+ return Nan::ThrowError(ParseError(ex.what()));
+ } catch (const mbgl::util::Exception &ex) {
return Nan::ThrowError(ex.what());
}
@@ -459,6 +478,11 @@ void NodeMap::startRender(NodeMap::RenderOptions options) {
uv_ref(reinterpret_cast<uv_handle_t *>(async));
}
+v8::Local<v8::Value> NodeMap::ParseError(const char* msg) {
+ v8::Local<v8::Value> argv[] = { Nan::New(msg).ToLocalChecked() };
+ return Nan::CallAsConstructor(Nan::New(parseError), 1, argv).ToLocalChecked();
+}
+
void NodeMap::renderFinished() {
assert(req);
@@ -480,16 +504,19 @@ void NodeMap::renderFinished() {
v8::Local<v8::Object> target = Nan::New<v8::Object>();
if (error) {
- std::string errorMessage;
+ v8::Local<v8::Value> err;
try {
std::rethrow_exception(error);
+ assert(false);
+ } catch (const mbgl::util::StyleParseException& ex) {
+ err = ParseError(ex.what());
} catch (const std::exception& ex) {
- errorMessage = ex.what();
+ err = Nan::Error(ex.what());
}
v8::Local<v8::Value> argv[] = {
- Nan::Error(errorMessage.c_str())
+ err
};
// This must be empty to be prepared for the next render call.
diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp
index 19df095481..52fc1ef659 100644
--- a/platform/node/src/node_map.hpp
+++ b/platform/node/src/node_map.hpp
@@ -37,6 +37,7 @@ public:
~NodeMap();
static Nan::Persistent<v8::Function> constructor;
+ static Nan::Persistent<v8::Object> parseError;
static void Init(v8::Local<v8::Object>);
@@ -67,6 +68,8 @@ public:
static void DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>&);
static void QueryRenderedFeatures(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static v8::Local<v8::Value> ParseError(const char* msg);
+
void startRender(RenderOptions options);
void renderFinished();
diff --git a/platform/node/test/js/map.test.js b/platform/node/test/js/map.test.js
index 2223e54aaa..4a71d72046 100644
--- a/platform/node/test/js/map.test.js
+++ b/platform/node/test/js/map.test.js
@@ -323,6 +323,10 @@ test('Map', function(t) {
map.load('""');
}, /Failed to parse style: style must be an object/);
+ t.throws(function() {
+ map.load('""');
+ }, mbgl.ParseError);
+
map.release();
t.end();
});
@@ -341,6 +345,10 @@ test('Map', function(t) {
t.throws(function() {
map.load('invalid');
+ }, mbgl.ParseError);
+
+ t.throws(function() {
+ map.load('invalid');
}, /Failed to parse style: 0 - Invalid value./);
});
diff --git a/src/mbgl/style/sources/raster_source.cpp b/src/mbgl/style/sources/raster_source.cpp
index 53f29d660b..c2f96dbd55 100644
--- a/src/mbgl/style/sources/raster_source.cpp
+++ b/src/mbgl/style/sources/raster_source.cpp
@@ -5,6 +5,7 @@
#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/mapbox.hpp>
+#include <mbgl/util/exception.hpp>
namespace mbgl {
namespace style {
@@ -59,7 +60,7 @@ void RasterSource::loadDescription(FileSource& fileSource) {
conversion::Error error;
optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
if (!tileset) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ observer->onSourceError(*this, std::make_exception_ptr(util::StyleParseException(error.message)));
return;
}
diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp
index ccdd453c75..6cede8fae9 100644
--- a/src/mbgl/style/sources/vector_source.cpp
+++ b/src/mbgl/style/sources/vector_source.cpp
@@ -6,6 +6,7 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/constants.hpp>
+#include <mbgl/util/exception.hpp>
namespace mbgl {
namespace style {
@@ -56,7 +57,7 @@ void VectorSource::loadDescription(FileSource& fileSource) {
conversion::Error error;
optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
if (!tileset) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ observer->onSourceError(*this, std::make_exception_ptr(util::StyleParseException(error.message)));
return;
}