Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.cpp

Issue 2116563003: [DevTools] Report unhandled exceptions and promise rejections through Runtime. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tests pass Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/v8_inspector/V8ConsoleMessage.h" 5 #include "platform/v8_inspector/V8ConsoleMessage.h"
6 6
7 #include "platform/v8_inspector/InspectedContext.h" 7 #include "platform/v8_inspector/InspectedContext.h"
8 #include "platform/v8_inspector/V8ConsoleAgentImpl.h" 8 #include "platform/v8_inspector/V8ConsoleAgentImpl.h"
9 #include "platform/v8_inspector/V8DebuggerImpl.h" 9 #include "platform/v8_inspector/V8DebuggerImpl.h"
10 #include "platform/v8_inspector/V8InspectorSessionImpl.h" 10 #include "platform/v8_inspector/V8InspectorSessionImpl.h"
11 #include "platform/v8_inspector/V8RuntimeAgentImpl.h"
11 #include "platform/v8_inspector/V8StackTraceImpl.h" 12 #include "platform/v8_inspector/V8StackTraceImpl.h"
12 #include "platform/v8_inspector/V8StringUtil.h" 13 #include "platform/v8_inspector/V8StringUtil.h"
13 #include "platform/v8_inspector/public/V8DebuggerClient.h" 14 #include "platform/v8_inspector/public/V8DebuggerClient.h"
14 15
15 namespace blink { 16 namespace blink {
16 17
17 namespace { 18 namespace {
18 19
19 String messageSourceValue(MessageSource source) 20 String messageSourceValue(MessageSource source)
20 { 21 {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 } 55 }
55 56
56 String messageLevelValue(MessageLevel level) 57 String messageLevelValue(MessageLevel level)
57 { 58 {
58 switch (level) { 59 switch (level) {
59 case DebugMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum: :Debug; 60 case DebugMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum: :Debug;
60 case LogMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum::L og; 61 case LogMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum::L og;
61 case WarningMessageLevel: return protocol::Console::ConsoleMessage::LevelEnu m::Warning; 62 case WarningMessageLevel: return protocol::Console::ConsoleMessage::LevelEnu m::Warning;
62 case ErrorMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum: :Error; 63 case ErrorMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum: :Error;
63 case InfoMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum:: Info; 64 case InfoMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum:: Info;
64 case RevokedErrorMessageLevel: return protocol::Console::ConsoleMessage::Lev elEnum::RevokedError;
65 } 65 }
66 return protocol::Console::ConsoleMessage::LevelEnum::Log; 66 return protocol::Console::ConsoleMessage::LevelEnum::Log;
67 } 67 }
68 68
69 const unsigned maxConsoleMessageCount = 1000; 69 const unsigned maxConsoleMessageCount = 1000;
70 const unsigned maxArrayItemsLimit = 10000; 70 const unsigned maxArrayItemsLimit = 10000;
71 const unsigned maxStackDepthLimit = 32; 71 const unsigned maxStackDepthLimit = 32;
72 72
73 class V8ValueStringBuilder { 73 class V8ValueStringBuilder {
74 public: 74 public:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 double timestampMS, 201 double timestampMS,
202 MessageSource source, 202 MessageSource source,
203 MessageLevel level, 203 MessageLevel level,
204 const String16& message, 204 const String16& message,
205 const String16& url, 205 const String16& url,
206 unsigned lineNumber, 206 unsigned lineNumber,
207 unsigned columnNumber, 207 unsigned columnNumber,
208 std::unique_ptr<V8StackTrace> stackTrace, 208 std::unique_ptr<V8StackTrace> stackTrace,
209 int scriptId, 209 int scriptId,
210 const String16& requestIdentifier) 210 const String16& requestIdentifier)
211 : m_timestamp(timestampMS / 1000.0) 211 : m_origin(V8MessageOrigin::kConsole)
212 , m_timestamp(timestampMS / 1000.0)
212 , m_source(source) 213 , m_source(source)
213 , m_level(level) 214 , m_level(level)
214 , m_message(message) 215 , m_message(message)
215 , m_url(url) 216 , m_url(url)
216 , m_lineNumber(lineNumber) 217 , m_lineNumber(lineNumber)
217 , m_columnNumber(columnNumber) 218 , m_columnNumber(columnNumber)
218 , m_stackTrace(std::move(stackTrace)) 219 , m_stackTrace(std::move(stackTrace))
219 , m_scriptId(scriptId) 220 , m_scriptId(scriptId)
220 , m_requestIdentifier(requestIdentifier) 221 , m_requestIdentifier(requestIdentifier)
221 , m_contextId(0) 222 , m_contextId(0)
222 , m_type(LogMessageType) 223 , m_type(LogMessageType)
223 , m_messageId(0) 224 , m_exceptionId(0)
224 , m_relatedMessageId(0) 225 , m_revokedExceptionId(0)
225 { 226 {
226 } 227 }
227 228
228 V8ConsoleMessage::~V8ConsoleMessage() 229 V8ConsoleMessage::~V8ConsoleMessage()
229 { 230 {
230 } 231 }
231 232
232 std::unique_ptr<protocol::Console::ConsoleMessage> V8ConsoleMessage::buildInspec torObject(V8InspectorSessionImpl* session, bool generatePreview) const 233 void V8ConsoleMessage::reportToFrontend(protocol::Console::Frontend* frontend, V 8InspectorSessionImpl* session, bool generatePreview) const
233 { 234 {
235 DCHECK_EQ(V8MessageOrigin::kConsole, m_origin);
234 std::unique_ptr<protocol::Console::ConsoleMessage> result = 236 std::unique_ptr<protocol::Console::ConsoleMessage> result =
235 protocol::Console::ConsoleMessage::create() 237 protocol::Console::ConsoleMessage::create()
236 .setSource(messageSourceValue(m_source)) 238 .setSource(messageSourceValue(m_source))
237 .setLevel(messageLevelValue(m_level)) 239 .setLevel(messageLevelValue(m_level))
238 .setText(m_message) 240 .setText(m_message)
239 .setTimestamp(m_timestamp) 241 .setTimestamp(m_timestamp)
240 .build(); 242 .build();
241 result->setType(messageTypeValue(m_type)); 243 result->setType(messageTypeValue(m_type));
242 result->setLine(static_cast<int>(m_lineNumber)); 244 result->setLine(static_cast<int>(m_lineNumber));
243 result->setColumn(static_cast<int>(m_columnNumber)); 245 result->setColumn(static_cast<int>(m_columnNumber));
244 if (m_scriptId) 246 if (m_scriptId)
245 result->setScriptId(String::number(m_scriptId)); 247 result->setScriptId(String::number(m_scriptId));
246 result->setUrl(m_url); 248 result->setUrl(m_url);
247 if (m_source == NetworkMessageSource && !m_requestIdentifier.isEmpty()) 249 if (m_source == NetworkMessageSource && !m_requestIdentifier.isEmpty())
248 result->setNetworkRequestId(m_requestIdentifier); 250 result->setNetworkRequestId(m_requestIdentifier);
249 if (m_contextId) 251 if (m_contextId)
250 result->setExecutionContextId(m_contextId); 252 result->setExecutionContextId(m_contextId);
251 appendArguments(result.get(), session, generatePreview); 253 std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>> args = wra pArguments(session, generatePreview);
254 if (args)
255 result->setParameters(std::move(args));
252 if (m_stackTrace) 256 if (m_stackTrace)
253 result->setStack(m_stackTrace->buildInspectorObject()); 257 result->setStack(m_stackTrace->buildInspectorObject());
254 if (m_messageId) 258 frontend->messageAdded(std::move(result));
255 result->setMessageId(m_messageId);
256 if (m_relatedMessageId)
257 result->setRelatedMessageId(m_relatedMessageId);
258 return result;
259 } 259 }
260 260
261 void V8ConsoleMessage::appendArguments(protocol::Console::ConsoleMessage* result , V8InspectorSessionImpl* session, bool generatePreview) const 261 std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>> V8ConsoleMessa ge::wrapArguments(V8InspectorSessionImpl* session, bool generatePreview) const
262 { 262 {
263 if (!m_arguments.size() || !m_contextId) 263 if (!m_arguments.size() || !m_contextId)
264 return; 264 return nullptr;
265 InspectedContext* inspectedContext = session->debugger()->getContext(session ->contextGroupId(), m_contextId); 265 InspectedContext* inspectedContext = session->debugger()->getContext(session ->contextGroupId(), m_contextId);
266 if (!inspectedContext) 266 if (!inspectedContext)
267 return; 267 return nullptr;
268 268
269 v8::Isolate* isolate = inspectedContext->isolate(); 269 v8::Isolate* isolate = inspectedContext->isolate();
270 v8::HandleScope handles(isolate); 270 v8::HandleScope handles(isolate);
271 v8::Local<v8::Context> context = inspectedContext->context(); 271 v8::Local<v8::Context> context = inspectedContext->context();
272 272
273 std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>> args = pro tocol::Array<protocol::Runtime::RemoteObject>::create(); 273 std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>> args = pro tocol::Array<protocol::Runtime::RemoteObject>::create();
274 if (m_type == TableMessageType && generatePreview) { 274 if (m_type == TableMessageType && generatePreview) {
275 v8::Local<v8::Value> table = m_arguments[0]->Get(isolate); 275 v8::Local<v8::Value> table = m_arguments[0]->Get(isolate);
276 v8::Local<v8::Value> columns = m_arguments.size() > 1 ? m_arguments[1]-> Get(isolate) : v8::Local<v8::Value>(); 276 v8::Local<v8::Value> columns = m_arguments.size() > 1 ? m_arguments[1]-> Get(isolate) : v8::Local<v8::Value>();
277 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = session->wrap Table(context, table, columns); 277 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = session->wrap Table(context, table, columns);
278 if (wrapped) 278 if (wrapped)
279 args->addItem(std::move(wrapped)); 279 args->addItem(std::move(wrapped));
280 else 280 else
281 args = nullptr; 281 args = nullptr;
282 } else { 282 } else {
283 for (size_t i = 0; i < m_arguments.size(); ++i) { 283 for (size_t i = 0; i < m_arguments.size(); ++i) {
284 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = session-> wrapObject(context, m_arguments[i]->Get(isolate), "console", generatePreview); 284 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = session-> wrapObject(context, m_arguments[i]->Get(isolate), "console", generatePreview);
285 if (!wrapped) { 285 if (!wrapped) {
286 args = nullptr; 286 args = nullptr;
287 break; 287 break;
288 } 288 }
289 args->addItem(std::move(wrapped)); 289 args->addItem(std::move(wrapped));
290 } 290 }
291 } 291 }
292 if (args) 292 return args;
293 result->setParameters(std::move(args)); 293 }
294
295 void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, V 8InspectorSessionImpl* session, bool generatePreview) const
296 {
297 if (m_origin == V8MessageOrigin::kException) {
298 // TODO(dgozman): unify with InjectedScript::createExceptionDetails.
299 std::unique_ptr<protocol::Runtime::ExceptionDetails> details = protocol: :Runtime::ExceptionDetails::create().setText(m_message).build();
300 details->setUrl(m_url);
301 details->setLine(static_cast<int>(m_lineNumber));
kozy 2016/07/08 18:48:59 Exception details line and columns will be zero-ba
dgozman 2016/07/08 18:56:41 That's good! We'll unify them.
302 details->setColumn(static_cast<int>(m_columnNumber));
303 if (m_scriptId)
304 details->setScriptId(String::number(m_scriptId));
305 if (m_stackTrace)
306 details->setStack(m_stackTrace->buildInspectorObject());
307
308 std::unique_ptr<protocol::Runtime::RemoteObject> exception = wrapExcepti on(session, generatePreview);
309
310 if (exception)
311 frontend->exceptionUnhandled(m_exceptionId, m_timestamp, std::move(d etails), std::move(exception), m_contextId);
312 else
313 frontend->exceptionUnhandled(m_exceptionId, m_timestamp, std::move(d etails));
314 return;
315 }
316 if (m_origin == V8MessageOrigin::kRevokedException) {
317 frontend->exceptionRevoked(m_timestamp, m_message, m_revokedExceptionId) ;
318 return;
319 }
320 NOTREACHED();
321 }
322
323 std::unique_ptr<protocol::Runtime::RemoteObject> V8ConsoleMessage::wrapException (V8InspectorSessionImpl* session, bool generatePreview) const
324 {
325 if (!m_arguments.size() || !m_contextId)
326 return nullptr;
327 DCHECK_EQ(1u, m_arguments.size());
328 InspectedContext* inspectedContext = session->debugger()->getContext(session ->contextGroupId(), m_contextId);
329 if (!inspectedContext)
330 return nullptr;
331
332 v8::Isolate* isolate = inspectedContext->isolate();
333 v8::HandleScope handles(isolate);
334 // TODO(dgozman): should we use different object group?
335 return session->wrapObject(inspectedContext->context(), m_arguments[0]->Get( isolate), "console", generatePreview);
336 }
337
338 V8MessageOrigin V8ConsoleMessage::origin() const
339 {
340 return m_origin;
294 } 341 }
295 342
296 unsigned V8ConsoleMessage::argumentCount() const 343 unsigned V8ConsoleMessage::argumentCount() const
297 { 344 {
298 return m_arguments.size(); 345 return m_arguments.size();
299 } 346 }
300 347
301 MessageType V8ConsoleMessage::type() const 348 MessageType V8ConsoleMessage::type() const
302 { 349 {
303 return m_type; 350 return m_type;
(...skipping 25 matching lines...) Expand all
329 message->m_type = type; 376 message->m_type = type;
330 if (messageArguments.size()) { 377 if (messageArguments.size()) {
331 message->m_contextId = context->contextId(); 378 message->m_contextId = context->contextId();
332 message->m_arguments.swap(messageArguments); 379 message->m_arguments.swap(messageArguments);
333 } 380 }
334 381
335 context->debugger()->client()->messageAddedToConsole(context->contextGroupId (), message->m_source, message->m_level, message->m_message, message->m_url, mes sage->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); 382 context->debugger()->client()->messageAddedToConsole(context->contextGroupId (), message->m_source, message->m_level, message->m_message, message->m_url, mes sage->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get());
336 return message; 383 return message;
337 } 384 }
338 385
386 // static
387 std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForException(double ti mestampMS, const String16& messageText, const String16& url, unsigned lineNumber , unsigned columnNumber, std::unique_ptr<V8StackTrace> stackTrace, int scriptId, v8::Isolate* isolate, int contextId, v8::Local<v8::Value> exception, unsigned e xceptionId)
388 {
389 std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage( timestampMS, JSMessageSource, ErrorMessageLevel, messageText, url, lineNumber, c olumnNumber, std::move(stackTrace), scriptId, String16() /* requestIdentifier */ ));
390 message->m_exceptionId = exceptionId;
391 message->m_origin = V8MessageOrigin::kException;
392 if (contextId && !exception.IsEmpty()) {
393 message->m_contextId = contextId;
394 message->m_arguments.push_back(wrapUnique(new v8::Global<v8::Value>(isol ate, exception)));
395 }
396 return message;
397 }
398
399 // static
400 std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForRevokedException(do uble timestampMS, const String16& messageText, unsigned revokedExceptionId)
401 {
402 std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage( timestampMS, JSMessageSource, ErrorMessageLevel, messageText, String16(), 0, 0, nullptr, 0, String16()));
403 message->m_origin = V8MessageOrigin::kRevokedException;
404 message->m_revokedExceptionId = revokedExceptionId;
405 return message;
406 }
407
339 void V8ConsoleMessage::contextDestroyed(int contextId) 408 void V8ConsoleMessage::contextDestroyed(int contextId)
340 { 409 {
341 if (contextId != m_contextId) 410 if (contextId != m_contextId)
342 return; 411 return;
343 m_contextId = 0; 412 m_contextId = 0;
344 if (m_message.isEmpty()) 413 if (m_message.isEmpty())
345 m_message = "<message collected>"; 414 m_message = "<message collected>";
346 Arguments empty; 415 Arguments empty;
347 m_arguments.swap(empty); 416 m_arguments.swap(empty);
348 } 417 }
349 418
350 void V8ConsoleMessage::assignId(unsigned id)
351 {
352 m_messageId = id;
353 }
354
355 void V8ConsoleMessage::assignRelatedId(unsigned id)
356 {
357 m_relatedMessageId = id;
358 }
359
360 void V8ConsoleMessage::addArguments(v8::Isolate* isolate, int contextId, std::ve ctor<v8::Local<v8::Value>>* arguments)
361 {
362 if (!arguments || !contextId)
363 return;
364 m_contextId = contextId;
365 for (size_t i = 0; i < arguments->size(); ++i)
366 m_arguments.push_back(wrapUnique(new v8::Global<v8::Value>(isolate, argu ments->at(i))));
367 }
368
369 // ------------------------ V8ConsoleMessageStorage ---------------------------- 419 // ------------------------ V8ConsoleMessageStorage ----------------------------
370 420
371 V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8DebuggerImpl* debugger, int c ontextGroupId) 421 V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8DebuggerImpl* debugger, int c ontextGroupId)
372 : m_debugger(debugger) 422 : m_debugger(debugger)
373 , m_contextGroupId(contextGroupId) 423 , m_contextGroupId(contextGroupId)
374 , m_expiredCount(0) 424 , m_expiredCount(0)
375 { 425 {
376 } 426 }
377 427
378 V8ConsoleMessageStorage::~V8ConsoleMessageStorage() 428 V8ConsoleMessageStorage::~V8ConsoleMessageStorage()
379 { 429 {
380 clear(); 430 clear();
381 } 431 }
382 432
383 void V8ConsoleMessageStorage::addMessage(std::unique_ptr<V8ConsoleMessage> messa ge) 433 void V8ConsoleMessageStorage::addMessage(std::unique_ptr<V8ConsoleMessage> messa ge)
384 { 434 {
385 if (message->type() == ClearMessageType) 435 if (message->type() == ClearMessageType)
386 clear(); 436 clear();
387 437
388 V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_conte xtGroupId); 438 V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_conte xtGroupId);
389 if (session) 439 if (session) {
390 session->consoleAgent()->messageAdded(message.get()); 440 if (message->origin() == V8MessageOrigin::kConsole)
441 session->consoleAgent()->messageAdded(message.get());
442 else
443 session->runtimeAgent()->exceptionMessageAdded(message.get());
444 }
391 445
392 DCHECK(m_messages.size() <= maxConsoleMessageCount); 446 DCHECK(m_messages.size() <= maxConsoleMessageCount);
393 if (m_messages.size() == maxConsoleMessageCount) { 447 if (m_messages.size() == maxConsoleMessageCount) {
394 ++m_expiredCount; 448 ++m_expiredCount;
395 m_messages.pop_front(); 449 m_messages.pop_front();
396 } 450 }
397 m_messages.push_back(std::move(message)); 451 m_messages.push_back(std::move(message));
398 } 452 }
399 453
400 void V8ConsoleMessageStorage::clear() 454 void V8ConsoleMessageStorage::clear()
401 { 455 {
402 m_messages.clear(); 456 m_messages.clear();
403 m_expiredCount = 0; 457 m_expiredCount = 0;
404 V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_conte xtGroupId); 458 V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_conte xtGroupId);
405 if (session) { 459 if (session) {
406 session->consoleAgent()->reset(); 460 session->consoleAgent()->reset();
407 session->releaseObjectGroup("console"); 461 session->releaseObjectGroup("console");
408 session->client()->consoleCleared(); 462 session->client()->consoleCleared();
409 } 463 }
410 } 464 }
411 465
412 void V8ConsoleMessageStorage::contextDestroyed(int contextId) 466 void V8ConsoleMessageStorage::contextDestroyed(int contextId)
413 { 467 {
414 for (size_t i = 0; i < m_messages.size(); ++i) 468 for (size_t i = 0; i < m_messages.size(); ++i)
415 m_messages[i]->contextDestroyed(contextId); 469 m_messages[i]->contextDestroyed(contextId);
416 } 470 }
417 471
418 } // namespace blink 472 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698