|
13 | 13 | #include "platform/v8_inspector/public/V8Inspector.h"
|
14 | 14 | #include "platform/v8_inspector/public/V8InspectorClient.h"
|
15 | 15 | #include "platform/v8_inspector/public/V8InspectorSession.h"
|
| 16 | +#include "platform/v8_inspector/public/V8StackTrace.h" |
16 | 17 | #include "platform/inspector_protocol/FrontendChannel.h"
|
17 | 18 | #include "platform/inspector_protocol/String16.h"
|
18 | 19 | #include "platform/inspector_protocol/Values.h"
|
@@ -175,6 +176,9 @@ class AgentImpl {
|
175 | 176 | bool IsConnected() { return state_ == State::kConnected; }
|
176 | 177 | void WaitForDisconnect();
|
177 | 178 |
|
| 179 | + void FatalException(v8::Local<v8::Value> error, |
| 180 | + v8::Local<v8::Message> message); |
| 181 | + |
178 | 182 | private:
|
179 | 183 | using MessageQueue = std::vector<std::pair<int, String16>>;
|
180 | 184 | enum class State { kNew, kAccepting, kConnected, kDone, kError };
|
@@ -334,6 +338,10 @@ class V8NodeInspector : public blink::V8InspectorClient {
|
334 | 338 | session_->dispatchProtocolMessage(message);
|
335 | 339 | }
|
336 | 340 |
|
| 341 | + blink::V8Inspector* inspector() { |
| 342 | + return inspector_.get(); |
| 343 | + } |
| 344 | + |
337 | 345 | private:
|
338 | 346 | AgentImpl* agent_;
|
339 | 347 | v8::Isolate* isolate_;
|
@@ -495,6 +503,46 @@ void AgentImpl::InstallInspectorOnProcess() {
|
495 | 503 | env->SetMethod(inspector, "wrapConsoleCall", InspectorWrapConsoleCall);
|
496 | 504 | }
|
497 | 505 |
|
| 506 | +String16 ToProtocolString(v8::Local<v8::Value> value) { |
| 507 | + if (value.IsEmpty() || value->IsNull() || value->IsUndefined() || |
| 508 | + !value->IsString()) { |
| 509 | + return String16(); |
| 510 | + } |
| 511 | + v8::Local<v8::String> string_value = v8::Local<v8::String>::Cast(value); |
| 512 | + wstring buffer(string_value->Length(), '\0'); |
| 513 | + string_value->Write(&buffer[0], 0, string_value->Length()); |
| 514 | + return String16(buffer); |
| 515 | +} |
| 516 | + |
| 517 | +void AgentImpl::FatalException(v8::Local<v8::Value> error, |
| 518 | + v8::Local<v8::Message> message) { |
| 519 | + if (!IsStarted()) |
| 520 | + return; |
| 521 | + auto env = parent_env_; |
| 522 | + v8::Local<v8::Context> context = env->context(); |
| 523 | + |
| 524 | + int script_id = message->GetScriptOrigin().ScriptID()->Value(); |
| 525 | + std::unique_ptr<blink::V8StackTrace> stack_trace = |
| 526 | + inspector_->inspector()->createStackTrace(message->GetStackTrace()); |
| 527 | + |
| 528 | + if (stack_trace && !stack_trace->isEmpty() && |
| 529 | + String16::fromInteger(script_id) == stack_trace->topScriptId()) { |
| 530 | + script_id = 0; |
| 531 | + } |
| 532 | + |
| 533 | + inspector_->inspector()->exceptionThrown( |
| 534 | + context, |
| 535 | + "Uncaught", |
| 536 | + error, |
| 537 | + ToProtocolString(message->Get()), |
| 538 | + ToProtocolString(message->GetScriptResourceName()), |
| 539 | + message->GetLineNumber(context).FromMaybe(0), |
| 540 | + message->GetStartColumn(context).FromMaybe(0), |
| 541 | + std::move(stack_trace), |
| 542 | + script_id); |
| 543 | + WaitForDisconnect(); |
| 544 | +} |
| 545 | + |
498 | 546 | // static
|
499 | 547 | void AgentImpl::ThreadCbIO(void* agent) {
|
500 | 548 | static_cast<AgentImpl*>(agent)->WorkerRunIO();
|
@@ -714,5 +762,11 @@ void Agent::WaitForDisconnect() {
|
714 | 762 | impl->WaitForDisconnect();
|
715 | 763 | }
|
716 | 764 |
|
| 765 | +void Agent::FatalException(v8::Local<v8::Value> error, |
| 766 | + v8::Local<v8::Message> message) { |
| 767 | + impl->FatalException(error, message); |
| 768 | +} |
| 769 | + |
| 770 | + |
717 | 771 | } // namespace inspector
|
718 | 772 | } // namespace node
|
0 commit comments