From 8fdc1251cd752fc7dc20ad9dac43a3f05d67b87e Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 11 Jan 2019 13:40:17 -0500 Subject: [PATCH] libdeno: pipe more exception information thru --- libdeno/binding.cc | 60 +++++++++++++++++++++++++++++++++++++++++ libdeno/libdeno_test.cc | 39 +++++++++++++++------------ 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/libdeno/binding.cc b/libdeno/binding.cc index ef5d5a2269..a1b3f20f16 100644 --- a/libdeno/binding.cc +++ b/libdeno/binding.cc @@ -83,6 +83,66 @@ std::string EncodeExceptionAsJSON(v8::Local context, // auto exception_str = message->Get(); CHECK(json_obj->Set(context, v8_str("message"), exception_str).FromJust()); + auto maybe_source_line = message->GetSourceLine(context); + if (!maybe_source_line.IsEmpty()) { + CHECK(json_obj + ->Set(context, v8_str("sourceLine"), + maybe_source_line.ToLocalChecked()) + .FromJust()); + } + + CHECK(json_obj + ->Set(context, v8_str("scriptResourceName"), + message->GetScriptResourceName()) + .FromJust()); + + auto maybe_line_number = message->GetLineNumber(context); + if (maybe_line_number.IsJust()) { + CHECK(json_obj + ->Set(context, v8_str("lineNumber"), + v8::Integer::New(isolate, maybe_line_number.FromJust())) + .FromJust()); + } + + CHECK(json_obj + ->Set(context, v8_str("startPosition"), + v8::Integer::New(isolate, message->GetStartPosition())) + .FromJust()); + + CHECK(json_obj + ->Set(context, v8_str("endPosition"), + v8::Integer::New(isolate, message->GetEndPosition())) + .FromJust()); + + CHECK(json_obj + ->Set(context, v8_str("errorLevel"), + v8::Integer::New(isolate, message->ErrorLevel())) + .FromJust()); + + auto maybe_start_column = message->GetStartColumn(context); + if (maybe_start_column.IsJust()) { + auto start_column = + v8::Integer::New(isolate, maybe_start_column.FromJust()); + CHECK( + json_obj->Set(context, v8_str("startColumn"), start_column).FromJust()); + } + + auto maybe_end_column = message->GetEndColumn(context); + if (maybe_end_column.IsJust()) { + auto end_column = v8::Integer::New(isolate, maybe_end_column.FromJust()); + CHECK(json_obj->Set(context, v8_str("endColumn"), end_column).FromJust()); + } + + CHECK(json_obj + ->Set(context, v8_str("isSharedCrossOrigin"), + v8::Boolean::New(isolate, message->IsSharedCrossOrigin())) + .FromJust()); + + CHECK(json_obj + ->Set(context, v8_str("isOpaque"), + v8::Boolean::New(isolate, message->IsOpaque())) + .FromJust()); + v8::Local frames; if (!stack_trace.IsEmpty()) { uint32_t count = static_cast(stack_trace->GetFrameCount()); diff --git a/libdeno/libdeno_test.cc b/libdeno/libdeno_test.cc index 5a4a930775..9873987ea8 100644 --- a/libdeno/libdeno_test.cc +++ b/libdeno/libdeno_test.cc @@ -172,13 +172,14 @@ TEST(LibDenoTest, SnapshotBug) { TEST(LibDenoTest, GlobalErrorHandling) { Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr}); EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "GlobalErrorHandling()")); - // We only check that it starts with this string, so we don't have to check - // the second frame, which contains line numbers in libdeno_test.js and may - // change over time. std::string expected = "{\"message\":\"ReferenceError: notdefined is not defined\"," - "\"frames\":[{\"line\":3,\"column\":2,\"functionName\":\"\"," - "\"scriptName\":\"helloworld.js\",\"isEval\":true," + "\"sourceLine\":\" " + "notdefined()\",\"scriptResourceName\":\"helloworld.js\"," + "\"lineNumber\":3,\"startPosition\":3,\"endPosition\":4,\"errorLevel\":8," + "\"startColumn\":1,\"endColumn\":2,\"isSharedCrossOrigin\":false," + "\"isOpaque\":false,\"frames\":[{\"line\":3,\"column\":2," + "\"functionName\":\"\",\"scriptName\":\"helloworld.js\",\"isEval\":true," "\"isConstructor\":false,\"isWasm\":false},"; std::string actual(deno_last_exception(d), 0, expected.length()); EXPECT_STREQ(expected.c_str(), actual.c_str()); @@ -228,10 +229,12 @@ TEST(LibDenoTest, LastException) { EXPECT_EQ(deno_last_exception(d), nullptr); EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "\n\nthrow Error('boo');\n\n")); EXPECT_STREQ(deno_last_exception(d), - "{\"message\":\"Error: boo\"," - "\"frames\":[{\"line\":3,\"column\":7," - "\"functionName\":\"\",\"scriptName\":\"a.js\"," - "\"isEval\":false," + "{\"message\":\"Error: boo\",\"sourceLine\":\"throw " + "Error('boo');\",\"scriptResourceName\":\"a.js\",\"lineNumber\":" + "3,\"startPosition\":8,\"endPosition\":9,\"errorLevel\":8," + "\"startColumn\":6,\"endColumn\":7,\"isSharedCrossOrigin\":" + "false,\"isOpaque\":false,\"frames\":[{\"line\":3,\"column\":7," + "\"functionName\":\"\",\"scriptName\":\"a.js\",\"isEval\":false," "\"isConstructor\":false,\"isWasm\":false}]}"); deno_delete(d); } @@ -240,14 +243,16 @@ TEST(LibDenoTest, EncodeErrorBug) { Deno* d = deno_new(deno_config{0, empty, empty, nullptr, nullptr}); EXPECT_EQ(deno_last_exception(d), nullptr); EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "eval('a')")); - EXPECT_STREQ(deno_last_exception(d), - "{\"message\":\"ReferenceError: a is not defined\"," - "\"frames\":[{\"line\":1,\"column\":1," - "\"functionName\":\"\",\"scriptName\":\"\"," - "\"isEval\":true," - "\"isConstructor\":false,\"isWasm\":false},{\"line\":1," - "\"column\":1,\"functionName\":\"\",\"scriptName\":\"a.js\"," - "\"isEval\":false,\"isConstructor\":false,\"isWasm\":false}]}"); + EXPECT_STREQ( + deno_last_exception(d), + "{\"message\":\"ReferenceError: a is not " + "defined\",\"sourceLine\":\"a\",\"lineNumber\":1,\"startPosition\":0," + "\"endPosition\":1,\"errorLevel\":8,\"startColumn\":0,\"endColumn\":1," + "\"isSharedCrossOrigin\":false,\"isOpaque\":false,\"frames\":[{\"line\":" + "1,\"column\":1,\"functionName\":\"\",\"scriptName\":\"\"," + "\"isEval\":true,\"isConstructor\":false,\"isWasm\":false},{\"line\":1," + "\"column\":1,\"functionName\":\"\",\"scriptName\":\"a.js\",\"isEval\":" + "false,\"isConstructor\":false,\"isWasm\":false}]}"); deno_delete(d); }