[node] capture invalid input data as ParseError objects
This allows us to distinguish them from other types of errors
This commit is contained in:
committed by
John Firebaugh
parent
1e454642c8
commit
30272924a9
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user